<template>
  <div class="bg-white pt-1 h-full" :class="{ 'pt-2': !!typeCode }">
    <Spin :spinning="isSpinning" style="margin-top: 50px">
      <div class="toolbar-wrap" v-show="isLoaded || isLaunched">
        <div :class="toolbarClass" :style="[{ marginTop: isInDrawer ? '-20px' : '-8px' }]">
          <Row class="pl-2">
            <Button
              type="primary"
              class="cyan"
              @click="saveDraft"
              :disabled="isDoLoading && !isLoadTimeExceeded"
              v-if="formRowData.aryButton.some((item) => item.name === 'save')"
            >
              <template #icon>
                <SaveOutlined />
              </template>
              {{ btnSaveName }}
            </Button>
            <Button
              type="primary"
              class="ml-2 green"
              :disabled="isDoLoading && !isLoadTimeExceeded"
              @click="toolbarSubmit"
              v-if="formRowData.aryButton.some((item) => item.name === 'commit')"
            >
              <template #icon>
                <Icon icon="clarity:success-standard-line" />
              </template>
              {{ btnAgreeName }}
            </Button>
            <Button
              type="primary"
              class="ml-2"
              :disabled="isDoLoading && !isLoadTimeExceeded"
              @click="handleCountersign"
              v-if="formRowData.aryButton.some((item) => item.name === 'plus') && !isPlusDescShow"
            >
              <template #icon>
                <Icon icon="ant-design:user-add-outlined" />
              </template>
              {{ btnPlusName }}
            </Button>
            <Button
              type="primary"
              class="ml-2"
              :disabled="isDoLoading && !isLoadTimeExceeded"
              @click="returnFlow"
              v-if="formRowData.aryButton.some((item) => item.name === 'return')"
            >
              <template #icon>
                <RollbackOutlined />
              </template>
              {{ btnReturnName }}
            </Button>
            <Popconfirm
              placement="top"
              title="确定删除吗？"
              ok-text="确定"
              cancel-text="取消"
              @confirm="delFlow"
            >
              <Button
                type="primary"
                class="ml-2 orange"
                :disabled="isDoLoading && !isLoadTimeExceeded"
                v-if="formRowData.aryButton.some((item) => item.name === 'del')"
              >
                <template #icon>
                  <DeleteOutlined />
                </template>
                {{ btnDelName }}
              </Button>
            </Popconfirm>
            <Button
              type="primary"
              class="ml-2"
              :disabled="isDoLoading && !isLoadTimeExceeded"
              @click="handleDistribute"
              v-if="formRowData.aryButton.some((item) => item.name === 'distribute')"
            >
              <template #icon>
                <Icon icon="clarity:deploy-line" />
              </template>
              {{ btnDistributeName }}
            </Button>

            <Popconfirm
              placement="top"
              title="确定要直送给返回者吗？"
              ok-text="确定"
              cancel-text="取消"
              @confirm="handleToRetuner"
            >
              <Button
                type="primary"
                class="ml-2"
                :disabled="isDoLoading && !isLoadTimeExceeded"
                v-if="formRowData.aryButton.some((item) => item.name === 'toRetuner')"
              >
                <template #icon>
                  <SelectOutlined />
                </template>
                {{ btnToReturnerName }}
              </Button>
            </Popconfirm>

            <Popconfirm
              placement="top"
              title="确定要挂起吗？"
              ok-text="确定"
              cancel-text="取消"
              @confirm="handleSuspend"
            >
              <Button
                type="primary"
                class="ml-2"
                :disabled="isDoLoading && !isLoadTimeExceeded"
                v-if="formRowData.aryButton.some((item) => item.name === 'suspend')"
              >
                <template #icon>
                  <PauseCircleOutlined />
                </template>
                {{ btnSuspendName }}
              </Button>
            </Popconfirm>

            <Popconfirm
              placement="top"
              title="确定要恢复吗？"
              ok-text="确定"
              cancel-text="取消"
              @confirm="handleResume"
            >
              <Button
                type="primary"
                class="ml-2"
                :disabled="isDoLoading && !isLoadTimeExceeded"
                v-if="formRowData.aryButton.some((item) => item.name === 'resume')"
              >
                <template #icon>
                  <RightCircleOutlined />
                </template>
                {{ btnResumeName }}
              </Button>
            </Popconfirm>

            <Popconfirm
              placement="top"
              title="确定放弃吗？"
              ok-text="确定"
              cancel-text="取消"
              @confirm="discardFlow"
            >
              <Button
                type="primary"
                class="ml-2"
                :disabled="isDoLoading && !isLoadTimeExceeded"
                v-if="formRowData.aryButton.some((item) => item.name === 'discard')"
              >
                <template #icon>
                  <ClearOutlined />
                </template>
                {{ btnDiscardName }}
              </Button>
            </Popconfirm>

            <Popconfirm
              placement="top"
              title="确定已阅吗？"
              ok-text="确定"
              cancel-text="取消"
              @confirm="readedFlow"
            >
              <Button
                type="primary"
                class="ml-2"
                :disabled="isDoLoading && !isLoadTimeExceeded"
                v-if="formRowData.aryButton.some((item) => item.name === 'readed')"
              >
                <template #icon>
                  <CheckOutlined />
                </template>
                {{ btnReadedName }}
              </Button>
            </Popconfirm>

            <Popconfirm
              placement="top"
              title="确定拒绝吗？"
              ok-text="确定"
              cancel-text="取消"
              @confirm="disagreeFlow"
            >
              <Button
                type="primary"
                class="ml-2"
                :disabled="isDoLoading && !isLoadTimeExceeded"
                v-if="formRowData.aryButton.some((item) => item.name === 'disagree')"
              >
                <template #icon>
                  <CloseCircleOutlined />
                </template>
                {{ btnDisagreeName }}
              </Button>
            </Popconfirm>

            <Popconfirm
              placement="top"
              title="确定同意并结束吗？"
              ok-text="确定"
              cancel-text="取消"
              @confirm="finishAgreeFlow"
            >
              <Button
                type="primary"
                class="ml-2"
                title="同意并结束"
                :disabled="isDoLoading && !isLoadTimeExceeded"
                v-if="formRowData.aryButton.some((item) => item.name === 'finishAgree')"
              >
                <template #icon>
                  <CheckSquareOutlined />
                </template>
                {{ btnFinishAgreeName }}
              </Button>
            </Popconfirm>

            <Button
              type="primary"
              class="ml-2"
              :title="btnTransferName"
              :disabled="isDoLoading && !isLoadTimeExceeded"
              @click="handleTransfer"
              v-if="formRowData.aryButton.some((item) => item.name === 'transfer')"
            >
              <template #icon>
                <FileDoneOutlined />
              </template>
              {{ btnTransferName }}
            </Button>

            <Button
              type="primary"
              class="ml-2 light-blue"
              :disabled="isDoLoading && !isLoadTimeExceeded"
              @click="openFlowChartInfoDrawer"
              v-if="
                currentRoute?.query.isDebug ||
                formRowData.aryButton.some((item) => item.name === 'chart')
              "
            >
              <template #icon>
                <PartitionOutlined />
              </template>
              流程图
            </Button>
            <Button
              type="primary"
              class="ml-2 light-blue"
              :disabled="isDoLoading && !isLoadTimeExceeded"
              :loading="isDownloadZip"
              @click="handleDownloadZip"
              v-if="formRowData.aryButton.some((item) => item.name === 'zip')"
            >
              <template #icon>
                <FileZipOutlined />
              </template>
              打包
            </Button>
            <!-- <Button type="primary"  class="ml-2">
          <template #icon><HeartOutlined /></template>
          关注
        </Button>
         -->
            <Dropdown>
              <Button
                type="primary"
                class="ml-2"
                v-show="false"
                :disabled="isDoLoading && !isLoadTimeExceeded"
                ><template #icon>
                  <PrinterOutlined />
                </template>
                打印
              </Button>
              <template #overlay>
                <Menu @click="onClickMenu">
                  <MenuItem key="form"> 打印表单 </MenuItem>
                  <MenuItem key="all"> 打印全部 </MenuItem>
                  <MenuItem v-for="(item, index) in formRowData.aryView" :key="item.id">
                    {{ item.name }}
                  </MenuItem>
                </Menu>
              </template>
            </Dropdown>

            <Button
              type="primary"
              class="ml-2"
              @click="handleManager"
              v-if="
                formRowData.aryButton.some((item) => item.name === 'manage') &&
                !currentRoute?.query.isDebug
              "
            >
              <template #icon>
                <SettingOutlined />
              </template>
              管理
            </Button>
            <Button
              type="primary"
              class="ml-2"
              @click="handleDebug"
              v-if="formRowData.aryButton.some((item) => item.name === 'debug')"
            >
              <template #icon>
                <Icon icon="clarity:bug-line" />
              </template>
              调试
            </Button>
            <Button
              type="primary"
              class="ml-2"
              @click="handleRefresh"
              v-if="formRowData.aryButton.some((item) => item.name === 'debug')"
            >
              <template #icon>
                <Icon icon="clarity:refresh-line" />
              </template>
              刷新
            </Button>
          </Row>
          <Row
            class="h-8 flex justify-items-center items-center pl-2"
            v-for="(action, index) in toActions"
            :key="index"
            v-show="!formRowData.isNotShowNextUsers"
            style="background-color: white"
          >
            <Col :span="2">
              <span style="color:{{ action.color }}">{{ action.title }}</span
              >：</Col
            >
            <Col :span="22">
              <div class="flex m-2">
                <!-- 当为条件分支时才有属性 XorActionSelected，如果没有条件分支时，也应有此checkBox，所以不能用v-if  -->
                <Checkbox
                  :id="`XOR${action.id}`"
                  name="XorActionSelected"
                  :value="action.internalName"
                  style="display: none"
                  :checked="action.xorChecked"
                  v-show="false && action.hasOwnProperty('XorActionSelected')"
                />
                <span v-for="(checker, indexChecker) in action.checkers" :key="indexChecker">
                  <Checkbox
                    :name="`WorkflowAction_${action.id}`"
                    v-model:checked="checker.checked"
                    :disabled="checker.disabled"
                    @click="checkXOR(action.id, checker, index)"
                    style="vertical-align: middle"
                  >
                    {{ checker.realName }}
                  </Checkbox>
                </span>
                <Tooltip
                  title="全选"
                  v-if="action.checkers.length >= 3 && action.checkers.some((it) => !it.disabled)"
                  ><span
                    style="color: #0a67ca; cursor: pointer; margin-top: 2px; margin-left: 3px"
                    @click="handleSelectAllOnAction(action.checkers, index)"
                    >全选
                    <!-- <CheckSquareOutlined
                      style="color: #0a67ca; cursor: pointer"
                    /> -->
                  </span>
                </Tooltip>
                <Button
                  type="primary"
                  class="ml-2"
                  @click="selectUser(action, index, action.isBtnXor)"
                  v-if="action.isBtnSelUser"
                >
                  选择
                </Button>
                <span v-if="action.hasOwnProperty('expireHour')" class="pl-2"
                  >完成时间：{{ action.expireHour }}{{ action.expireUnit }}
                </span>
                <span v-if="matchJson.hasOwnProperty('isDelayed')" class="pl-2">
                  <ClockCircleOutlined class="mr-2" style="color: #0fb3f3" />
                  <span v-if="matchJson.isCanPrivUserModifyDelayDate">
                    <Checkbox :name="isDelayed" v-model:checked="matchJson.isDelayed" :value="1">
                      延时
                    </Checkbox>
                    <Input
                      v-model:value="matchJson.timeDelayedValue"
                      placeholder="时长"
                      style="width: 50px"
                    />
                    <Select
                      class="ml-2"
                      v-model:value="matchJson.timeDelayedUnit"
                      placeholder="请选择单位"
                      style="width: 80px"
                    >
                      <SelectOption :value="0">天</SelectOption>
                      <SelectOption :value="1">小时</SelectOption>
                      <SelectOption :value="2">工作日</SelectOption>
                      <SelectOption :value="3">工作小时</SelectOption>
                    </Select>
                  </span>
                  <span v-else>
                    {{ matchJson.timeDelayedValue }} {{ matchJson.timeDelayedUnitDesc }}
                  </span>
                </span>
              </div>
            </Col>
          </Row>
          <Row
            class="flex items-center pl-2"
            v-if="matchJson.hasOwnProperty('isMatchUserException') && matchJson.isMultiDept"
            style="background-color: white"
          >
            <Col :span="2"> 请选择部门 </Col>
            <Col :span="22">
              <RadioGroup
                v-model:value="selectDeptCode"
                name="deptOfUserWithMultiDept"
                @change="onSelDept"
              >
                <Radio
                  :value="dept.deptCode"
                  v-for="(dept, indexDept) in matchJson.multiDepts"
                  :key="indexDept"
                >
                  {{ dept.deptName }}
                </Radio>
              </RadioGroup>
              <!-- <div class="flex">
          <span v-for="(dept, indexDept) in matchJson.multiDepts" :key="indexDept">
            <Radio
              name="deptOfUserWithMultiDept"
              :value="dept.deptCode"
              @click="onSelDept(dept.deptCode)"
            >
              {{ dept.deptName }}
            </Radio>
          </span>
        </div> -->
            </Col>
          </Row>
          <Row v-if="formRowData.isPlus" class="m-2" style="background-color: white">
            <Col :span="24"> 您正在进行加签</Col>
          </Row>
          <Row v-show="isPlusDescShow" class="m-2" style="background-color: white">
            <Col :span="24"
              >{{ formRowData.plusDesc }}
              <Popconfirm
                placement="top"
                title="确定取消加签么？"
                ok-text="确定"
                cancel-text="取消"
                @confirm="delPlus"
              >
                <Icon
                  icon="clarity:times-line"
                  class="cursor-pointer"
                  color="red"
                  title="删除加签"
                />
              </Popconfirm>
            </Col>
          </Row>
          <Row class="flex items-center pl-2 pt-2" style="background-color: white">
            <Col :span="4" v-if="formRowData.isFlowLevelDisplay && !formRowData.isFlowStarted">
              <FormItem label="">
                <RadioGroup name="radioGroup" v-model:value="formRowData.cwsWorkflowLevel">
                  <Radio :value="0">普通</Radio>
                  <Radio :value="1">重要</Radio>
                  <Radio :value="2">紧急</Radio>
                  <!-- <Radio :value="-1">其他</Radio> -->
                </RadioGroup>
              </FormItem>
            </Col>
            <Col
              :span="4"
              v-if="formRowData.isFlowLevelDisplay && formRowData.isFlowStarted"
              class="ml-2"
            >
              <span title="普通" v-if="formRowData.cwsWorkflowLevel == 0">
                <Icon icon="clarity:control-lun-line" />
              </span>
              <span title="一般" v-if="formRowData.cwsWorkflowLevel == 1" style="color: orange">
                <Icon icon="clarity:control-lun-outline-badged" />
              </span>
              <span title="紧急" v-if="formRowData.cwsWorkflowLevel == 2" style="color: red">
                <Icon icon="clarity:control-lun-outline-badged" />
              </span>
              {{ formRowData.levelDesc }}
            </Col>
            <Col :span="2">
              <FormItem label="流程号" :labelCol="{ style: '100px' }">
                {{ formRowData.flowId }}
              </FormItem>
            </Col>
            <Col :span="16">
              <Form layout="horizontal" :label-col="{ span: 8 }">
                <Row>
                  <Col :span="8">
                    <FormItem label="标题" :labelCol="{ style: '100px' }">
                      <Input
                        v-model:value="formRowData.cwsWorkflowTitle"
                        :readonly="formRowData.isFlowStarted || formRowData.isFlowTitleReadonly"
                        placeholder="请输入标题"
                      />
                    </FormItem>
                  </Col>
                  <Col :span="6">
                    <FormItem label="发起人">
                      <Input
                        v-model:value="formRowData.starterRealName"
                        placeholder="请输入发起人"
                        readonly
                      />
                    </FormItem>
                  </Col>
                  <Col :span="8" v-if="flowIsRemarkShow && flowRemarkPos == 0">
                    <FormItem
                      :label="t('flow.leaveword')"
                      :labelCol="{ style: '100px' }"
                      style="margin-left: 5px; width: 90%"
                    >
                      <Input
                        v-model:value="formRowData.cwsWorkflowResult"
                        :placeholder="t('flow.leavewordPlaceholder')"
                        :name="'cwsWorkflowResult'"
                        :id="`cwsWorkflowResult_${getFormName}`"
                        @change="handleCwsWorkflowResultChange"
                      />
                    </FormItem>
                  </Col>
                </Row>
              </Form>
            </Col>
          </Row>
        </div>
      </div>
      <div v-if="matchBranchAndUserToActions.length && !formRowData.isFlowStarted">
        <ApprovalProcessLine
          class="mt-5"
          :matchBranchAndUserActions="matchBranchAndUserActions"
          @success="getMatchBranchAndUserData"
          ref="approvalProcessLineRef"
        />
      </div>
      <div
        v-show="isLoaded"
        class="border-1 border-solid border-gray-80 min-h-full"
        id="flowFormBox"
        style="border-radius: 8px"
      >
        <form
          id="flowForm"
          :name="getFormName"
          :formCode="formRowData ? formRowData.formCode : ''"
          :style="[
            { overflowX: isTab ? 'auto' : 'visible' },
            { background: '#fff' },
            { display: 'flex', flexDirection: 'column', borderRadius: '8px' },
          ]"
          pageType="flow"
        >
          <!-- eslint-disable-next-line vue/no-v-html -->
          <div id="contentBox" class="bg-white p-5" style="border-radius: 8px">
            <!-- <div id="contentForm" v-html="content"></div> -->
            <div :id="`content_${getFormName}`"></div>
          </div>
          <div id="formQueryBox" class="mt-2" v-show="formRowData.canQuery"></div>
          <input type="hidden" id="op" name="op" value="saveformvalue" />
          <input type="hidden" name="isAfterSaveformvalueBeforeXorCondSelect" />
          <input type="hidden" name="cws_id" :value="cwsId" />
          <input type="hidden" name="cwsIsFormLoaded" :value="cwsIsFormLoaded" />
          <input type="hidden" name="flowAction" />
        </form>

        <!--留言-->
        <div
          v-if="flowIsRemarkShow && flowRemarkPos == 1"
          class="p-16px bg-white mt-2"
          style="border-radius: 8px"
        >
          <div class="mb-3 mt-3 font-bold istitle"
            ><span>{{ t('flow.leaveword') }} </span></div
          ><div>
            <a-textarea
              v-model:value="formRowData.cwsWorkflowResult"
              :placeholder="t('flow.leavewordPlaceholder')"
              :name="'cwsWorkflowResult'"
              :id="`cwsWorkflowResult_${getFormName}`"
              @change="handleCwsWorkflowResultChange"
              :auto-size="{ minRows: 4, maxRows: 8 }"
              :multi="true"
              style="border-radius: 8px"
            />
          </div>

          <!--意见输入框常用语提示框-->
          <div id="phraseBox">
            <div class="phraseCnt">
              <div class="phraseClose" onclick="closeTipPhrase()">×</div>
              <div class="phraseAdd" @click="openTipPhraseModal">+</div>
              <div class="phraseIcon" style="clear: both"> </div>
            </div>
          </div>
        </div>
        <Row
          class="bg-white p-16px mt-2"
          style="border-radius: 8px"
          v-show="formRowData.isHasAttachment && isLoaded"
        >
          <template v-if="!isObjStoreEnabled && !isUseBreakpointResume">
            <Upload
              :file-list="fileList"
              :before-upload="beforeUpload"
              @remove="handleRemove"
              multiple="true"
            >
              <Button>
                <UploadOutlined />
                上传文件
              </Button>
            </Upload>
          </template>
          <template v-else>
            <Upload
              :file-list="fileList"
              :before-upload="beforeUpload"
              @remove="handleRemove"
              @change="handleFilesChange"
            >
              <a-button class="mt-1.5">
                <UploadOutlined />
                上传文件
              </a-button>
              <template #itemRender="{ file, actions }">
                <template v-if="getAttVisible(file)">
                  <div class="pt-2 w-350px flex justify-between">
                    <span :style="file.status === 'error' ? 'color: red' : ''">{{
                      file.name
                    }}</span>
                    <span>
                      <Tooltip title="暂停">
                        <PauseCircleOutlined
                          class="ml-2"
                          style="color: #0960bd"
                          v-if="isAttUploading(file)"
                          @click="handleUploadPause(file)"
                        />
                      </Tooltip>
                      <Tooltip title="上传">
                        <CaretRightOutlined
                          class="ml-2"
                          style="color: #0960bd"
                          v-if="isAttUploadPause(file)"
                          @click="handleUploadStart(file)"
                        />
                      </Tooltip>
                      <Tooltip title="取消">
                        <CloseOutlined
                          class="ml-2"
                          style="color: #0960bd"
                          v-if="isAttUploadStart(file)"
                          @click="handleUploadCancel(file, actions)"
                        />
                      </Tooltip>
                      <!-- <Tooltip title="预览">
                        <ProfileOutlined
                          class="ml-2"
                          style="color: #0960bd"
                          v-if="getAttUploadFinishedCanPreview(file)"
                          @click="handlePreviewAtt(file)"
                        />
                      </Tooltip> -->
                      <Tooltip title="查看">
                        <PictureOutlined
                          class="ml-2"
                          style="color: #0960bd"
                          v-if="getAttUploadFinishedIsImg(file)"
                          @click="handleShowImgAtt(file)"
                        />
                      </Tooltip>
                      <Tooltip title="下载">
                        <DownloadOutlined
                          class="ml-2"
                          style="color: #0960bd"
                          v-if="getAttUploadFinished(file)"
                          @click="handleDownloadAtt(file)"
                        />
                      </Tooltip>
                      <Popconfirm
                        placement="top"
                        title="确定删除吗？"
                        ok-text="确定"
                        cancel-text="取消"
                        v-if="formRowData.canDelAttachment && getAttUploadFinished(file)"
                        @confirm="handleRemoveFile(file, actions)"
                      >
                        <Tooltip title="删除">
                          <DeleteOutlined class="ml-2 mr-4" style="color: #ed6f6f" />
                        </Tooltip>
                      </Popconfirm>
                    </span>
                  </div>
                  <Progress :percent="getProgress(file)" />
                </template>
              </template>
            </Upload>
          </template>
        </Row>
        <div class="bg-white my-2" style="border-radius: 8px">
          <BasicTable
            @register="registerTable"
            v-show="formRowData.isHasAttachment && aryAttSize > 0"
          >
            <template #attTitle="{ record }">
              <div
                v-if="
                  record.previewUrl &&
                  record.previewUrl.length > 0 &&
                  record.previewUrl.indexOf('#') !== 0 &&
                  record.previewUrl.indexOf('&') !== 0
                "
                ><a
                  :href="record.previewUrl"
                  v-if="record.previewUrl.indexOf('@') !== 0"
                  target="_blank"
                  >{{ record.name }}</a
                >
                <a v-if="record.previewUrl.indexOf('@') === 0" @click="handlePreview(record)">{{
                  record.name
                }}</a>
              </div>
              <div v-else-if="record.previewUrl.indexOf('#') === 0">
                <a @click="handleWebOfficePreview(record)">{{ record.name }}</a>
              </div>
              <div v-else-if="record.previewUrl.indexOf('&') === 0">
                <a @click="handleOnlyofficePreview(record)">{{ record.name }}</a>
              </div>
              <div v-else>{{ record.name }}</div>
            </template>
            <template #action="{ record, index }">
              <TableAction
                :actions="[
                  {
                    icon: 'clarity:note-edit-line',
                    tooltip: '编辑',
                    onClick: handleEditOffice.bind(null, record),
                    ifShow: formRowData.canEditAttachment && isOfficeFile(record),
                  },
                  {
                    icon: 'ion:download-outline',
                    tooltip: '下载',
                    onClick: handleDownload.bind(null, record),
                    loading: record.isDownloadAtt ? true : false,
                  },
                  {
                    icon: 'ant-design:vertical-align-bottom-outlined',
                    tooltip: 'OFD下载',
                    ifShow:
                      formRowData.isWordDownloadByOfd == 1 &&
                      (record.name.split('.').length > 1
                        ? '.' + record.name.split('.').pop()
                        : '') == '.docx',
                    //ifShow: true,

                    onClick: handleDownloadOfd.bind(null, record),
                    loading: record.isDownloadAttOfd ? true : false,
                  },
                  {
                    icon: 'ant-design:delete-outlined',
                    tooltip: '删除',
                    color: 'error',
                    popConfirm: {
                      title: '是否确认删除',
                      confirm: handleDelete.bind(null, record, index),
                    },
                    ifShow: formRowData.canDelAttachment,
                  },
                  {
                    icon: 'ant-design:pic-center-outlined',
                    tooltip: '套红',
                    color: 'error',
                    onClick: handleSelTemplate.bind(null, record),
                    ifShow: record.canDocInRed,
                    loading: record.isDoDocInRed,
                  },
                  {
                    icon: 'ant-design:file-done-outlined',
                    tooltip: '盖章',
                    color: 'error',
                    onClick: handleSelStamp.bind(null, record),
                    ifShow: record.canSeal,
                    loading: record.isSeal ? true : false,
                  },
                ]"
              />
            </template>
          </BasicTable>
        </div>
        <div class="bg-white p-2" v-show="isLoaded" style="border-radius: 8px">
          <Tabs v-model:activeKey="activeTimeKey">
            <TabPane key="1" tab="处理过程" force-render>
              <BasicTable @register="registerHandleTable">
                <template #userRealName="{ record }">
                  <Tooltip>
                    <template #title>
                      <div v-if="record.userMobile">手机 {{ record.userMobile }}</div>
                      <div v-if="record.userPhone">固话 {{ record.userPhone }}</div>
                      <div v-if="record.userEmail">邮箱 {{ record.userEmail }}</div>
                    </template>
                    {{ record.userRealName }}
                  </Tooltip>
                </template>
                <template #privRealName="{ record }">
                  <Tooltip
                    ><template #title>
                      <div v-if="record.privUserMobile">手机 {{ record.privUserMobile }}</div>
                      <div v-if="record.privUserPhone">固话 {{ record.privUserPhone }}</div>
                      <div v-if="record.privUserEmail"
                        >邮箱 {{ record.privUserEmail }}</div
                      > </template
                    >{{ record.privRealName }}
                  </Tooltip>
                </template>
                <template #result="{ record }">
                  <span v-html="record.result"></span>
                </template>
              </BasicTable>
            </TabPane>
            <TabPane key="2" tab="时间线">
              <ProcessTimeLine
                :flowInfo="flowProcessData"
                :flowId="formRowData.flowId"
                :getFormName="getFormName"
                v-if="formRowData.flowId != '-1' && getFormName"
                ref="processTimeLineRef"
              />
            </TabPane>
          </Tabs>
        </div>
      </div>
      <!-- 回复 -->
      <div class="mt-2 mb-2">
        <ReplyView
          v-model:flowInfo="formRowData"
          v-if="formRowData.isReply && formRowData.isFlowStarted"
          @success="handleReplyViewSuccess"
        />
      </div>

      <Modal
        v-model:visible="returnFlowVisible"
        title="退回"
        @ok="handleReturnFlow"
        :confirmLoading="isReturning"
      >
        <div v-if="isReturnStyleFree" style="padding: 20px">
          <RadioGroup name="radioGroup" v-model:value="returnIdValueRadio">
            <Radio
              :value="item.returnId"
              v-for="(item, index) in returnResult"
              :key="index"
              style="display: flex"
              >{{ item.actionTitle }} {{ item.userRealName }}</Radio
            >
          </RadioGroup>
        </div>
        <div v-else style="padding: 20px">
          <RadioGroup
            name="CheckboxGroup"
            :options="aryReturnAction"
            v-model:value="returnIdValueRadio"
            style="display: flex; flex-direction: column"
          />
        </div>
      </Modal>

      <Modal v-model:visible="importVisible" title="导入" :closable="true">
        <template #footer>
          <Button @click="handleCancel">关闭</Button>
        </template>
        <div style="padding: 20px">
          <Row>
            <Col :span="8">
              <Button type="primary" @click="handleDownloadExcelTempl" :loading="isDownload"
                >下载模板</Button
              >
            </Col>
            <Col :span="8">
              <ImpExcel :isFiles="false" @raw-file="rawFileFn" dateFormat="YYYY-MM-DD">
                <a-button type="primary" class="mr-1" :loading="isImport"> 上传文件 </a-button>
              </ImpExcel>
            </Col>
          </Row>
        </div>
      </Modal>

      <SelectUser @register="registerModal" @success="handleCallBack" />
      <MatchBranchAndUserModal
        @register="matchJsonRegisterModal"
        @success="handleMatchJsonCallBack"
      />
      <SmartModuleRelateTableDrawer
        @register="registerSmartModuleRelateTableDrawer"
        @success="smartModuleRelateTableDrawerhandleSuccess"
        @close="initWindowFunc"
      />
      <SmartModuleSelDrawer
        @register="registerSmartModuleSelDrawer"
        @success="handleSmartModuleSelCallBack"
        @clear="clearSmartModuleSel"
        @close="initWindowFunc"
      />
      <SmartModuleDrawer
        @register="registerSmartModuleDrawer"
        @success="handleSmartModuleCallBack"
        @close="initWindowFunc"
        @edit-action="handleOpenEditDrawer"
      />
      <FlowChartDrawer @register="registerFlowChartDrawer" />
      <ProcessShowDrawer
        @register="registerProcessShowDrawer"
        @success="handleProcessShowCallBack"
      />
      <ProcessSelectDrawer
        @register="registerProcessSelectDrawer"
        @success="handleProcessSelect"
        @close="initWindowFunc"
      />
      <ProcessViewDrawer
        @register="registerProcessViewDrawer"
        @success="handleProcessViewCallBack"
      />
      <DebugDrawer @register="registerDebugDrawer" @success="handleDeBugCallBack" />
      <CountersignModal @register="registerCountersignModal" @success="handleCountersignCallBack" />
      <DistributeModal @register="registerDistributeModal" @success="handleDistributeCallBack" />
      <SelTemplateModal @register="registerSelTemplateModal" @success="handleSelTemplateCallBack" />
      <SelStampModal @register="registerSelStampModal" @success="handleSelStampCallBack" />
      <InputPwdModal @register="registerInputPwdModal" @success="handleInputPwdCallBack" />
      <WritePadModal @register="registerWritePadModal" @success="handleWritePadCallBack" />
      <TipPhraseModal @register="registerTipPhraseModal" @success="handleTipPhraseCallBack" />
      <SelDeptModal @register="registerSelDeptModal" @success="handleSelDeptCallBack" />
      <LocationMarkModal
        @register="registerLocationMarkModal"
        @success="handleLocationMarkCallBack"
      />
      <LocationMarkTdModal
        @register="registerLocationMarkTdModal"
        @success="handleLocationMarkCallBack"
      />
      <DesignIframe
        @register="registerModalDesignIframe"
        @success="handleSuccessDesignIframe"
        ref="ifrmRef"
      />
    </Spin>
  </div>
</template>
<script lang="ts">
  import {
    defineComponent,
    ref,
    unref,
    onMounted,
    h,
    watch,
    inject,
    nextTick,
    onActivated,
    onDeactivated,
    onUnmounted,
    computed,
    defineAsyncComponent,
  } from 'vue';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { ImpExcel } from '/@/components/Excel';
  import { useDrawer } from '/@/components/Drawer';
  import SmartModuleSelDrawer from '../smartModule/modules/smartModuleSelDrawer.vue';
  // import SmartModuleDrawer from '../smartModule/modules/smartModuleDrawer.vue';
  import ProcessShowDrawer from './processShowDrawer.vue';
  import ProcessSelectDrawer from './processSelectDrawer.vue';
  import ProcessViewDrawer from './processViewDrawer.vue';
  import ReplyView from './modules/ReplyView.vue';
  import { getIsDebug, getToken } from '/@/utils/auth';
  import { getShowImg } from '/@/api/system/system';
  import { bufToUrl } from '/@/utils/file/base64Conver';
  import { getVisualDownload } from '/@/api/module/module';
  import {
    selectFiles,
    deleteByField,
    isUploadFinished,
    getObjectByKey,
    uploadFileObjectFunc,
    deleteByUid,
    doPause,
    doStart,
    doCancel,
    UploadStatus,
  } from '/@/utils/uploadFile';
  import { useUploadFileStore } from '/@/store/modules/uploadFile';
  import { dateUtil as dayjs } from '/@/utils/dateUtil';

  import {
    getFlowProcess,
    getFlowProcessScript,
    getFinishAction,
    getListAttachment,
    getListAttachmentDelAtt,
    submitMyFile,
    getDiscardFlow,
    getSuspendFlow,
    getResumeFlow,
    getDelFlow,
    getReturnAction,
    getMatchBranchAndUser,
    getFlowInit,
    getDownload,
    downloadFile,
    getDelPlus,
    convertToRedDocument,
    sealDocument,
    getPhrases,
    delPhrase,
    getDelAttach,
    transfer,
    downloadZipFile,
    getReadedFlow,
    getDownloadOfd,
    getRunConnector,
    getFieldNamesInCond,
    getActionsOnBranch,
  } from '/@/api/process/process';
  import { useMultipleTabWithOutStore } from '/@/store/modules/multipleTab';
  import { DesignIframe } from '/@/views/system/workflow/flowManagement/modules/flowPicture/modules/modules/index';
  import {
    SaveOutlined,
    SettingOutlined,
    PartitionOutlined,
    PrinterOutlined,
    DeleteOutlined,
    UploadOutlined,
    SelectOutlined,
    RightCircleOutlined,
    RollbackOutlined,
    ClearOutlined,
    CloseCircleOutlined,
    FileDoneOutlined,
    ProfileOutlined,
    PictureOutlined,
    DownloadOutlined,
    ClockCircleOutlined,
    FileZipOutlined,
    CheckOutlined,
    CaretRightOutlined,
    CloseOutlined,
    PauseCircleOutlined,
    CheckSquareOutlined,
  } from '@ant-design/icons-vue';
  import {
    Button,
    CheckboxGroup,
    Row,
    Col,
    Checkbox,
    Upload,
    UploadProps,
    Radio,
    Input,
    Form,
    Modal,
    Spin,
    Popconfirm,
    Dropdown,
    Menu,
    MenuItem,
    MenuProps,
    Progress,
    Tooltip,
    Select,
    Tabs,
    TabPane,
  } from 'ant-design-vue';
  import Icon from '/@/components/Icon/index';
  import { BasicTable, useTable, TableAction } from '/@/components/Table';
  import { BasicColumn } from '/@/components/Table';
  import { SelectUser } from '/@/components/CustomComp';
  import { useModal } from '/@/components/Modal';
  import MatchBranchAndUserModal from './modules/MatchBranchAndUserModal.vue';
  import SmartModuleRelateTableDrawer from '../smartModule/modules/smartModuleRelateTableDrawer.vue'; //选择模块
  import FlowChartDrawer from './flowChartDrawer.vue';
  import CountersignModal from './modules/CountersignModal.vue';
  import DistributeModal from './modules/DistributeModal.vue';
  import SelTemplateModal from './modules/SelTemplateModal.vue';
  import SelStampModal from './modules/SelStampModal.vue';
  import InputPwdModal from './modules/InputPwdModal.vue';
  import WritePadModal from './modules/WritePadModal.vue';
  import TipPhraseModal from './modules/TipPhraseModal.vue';
  import SelDeptModal from './modules/SelDeptModal.vue';
  import LocationMarkModal from './modules/LocationMarkModal.vue';
  import { useGo } from '/@/hooks/web/usePage';
  import CurFormUtil from '/@/utils/form';
  import printJS from 'print-js';
  import {
    removeScript,
    removeLink,
    filterJS,
    ajaxGet,
    ajaxPost,
    ajaxGetJS,
    myConfirm,
    myMsg,
    ajaxPostJson,
    loadImg,
    initFormCtl,
    clearFormCtl,
    o,
    getServerInfo,
    isImage,
    loadImgInJar,
    setContentHtml,
  } from '/@/utils/utils';
  import DebugDrawer from './modules/debugDrawer.vue';
  import { useRoute } from 'vue-router';
  import { useUserStore } from '/@/store/modules/user';
  import {
    getVisualExportExcelRelate,
    getVisualImportExcelNest,
    getVisualDownloadExcelTemplForNest,
    getItemsForListModuleSel,
    getSelBatchForNest,
  } from '/@/api/module/module';
  import { downloadByData } from '/@/utils/file/download';
  import { useTabs } from '/@/hooks/web/useTabs';
  import { useRouter } from 'vue-router';
  import LocationMarkTdModal from './modules/LocationMarkTdModal.vue';
  import * as useFormJsFunc from '/@/assets/form_js';
  import ProcessTimeLine from './processTimeLine/ProcessTimeLine.vue';
  import ApprovalProcessLine from './approvalProcessLine/ApprovalProcessLine.vue';

  interface formRowData {
    cwsWorkflowTitle: string;
    cwsWorkflowResult?: string;
    cwsWorkflowLevel?: number; // 等级
    levelDesc?: string; // 等级描述
    flowId: string;
    starterRealName: string;
    actionId: string;
    myActionId: number;
    aryButton: Array<any>;
    isFlowLevelDisplay: boolean; // 是否显示流程等级
    hasView: boolean; // 是否有视图
    aryView: Array<any>; // 视图数组
    isFlowStarted: boolean; // 流程是否已启动
    isFlowTitleReadonly: boolean; // 流程标题是否只读
    formCode: string; // 表单编码
    isHasAttachment: boolean; // 表单是否带有附件
    isMyPlus: boolean; // 是否我加的加签
    isPlusBefore: boolean; // 是否为前加签
    plusDesc: string; // 加签的描述
    isPlus: boolean; // 是否为加签处理
    isNotShowNextUsers: boolean; // 是否不显示下一节点上的审核人
    isFlowManager: boolean; // 是否流程管理员
    isReply: boolean; // 能否回复
    flowStatus: number; // 流程状态
    canQuery: boolean; // 能否查询
    isDebug: boolean; // 是否为调试模式
    canDelAttachment: boolean; // 是否能删除附件
    isRemarkShowInProcessList: boolean; // 处理过程中是否显示留言
    officeEditor: string; // office编辑器 web-office或onlyoffice
    onlyofficeServerUrl: string; // onlyoffice服务器地址
    canEditAttachment: boolean; // 是否能编辑附件
    branchMode: number; // 分支模式，默认为多选
    isWordDownloadByOfd: number; //docx文件能否转成ofd格式下载
    deptFieldLimited: string; // 限定部门表单域
    deptLimited: string; // 限定部门
  }

  export default defineComponent({
    // eslint-disable-next-line vue/component-definition-name-casing
    name: 'processHandleView',
    components: {
      Button,
      SaveOutlined,
      SettingOutlined,
      // HeartOutlined,
      PartitionOutlined,
      PrinterOutlined,
      DeleteOutlined,
      SelectOutlined,
      RightCircleOutlined,
      PauseCircleOutlined,
      CaretRightOutlined,
      CloseOutlined,
      RollbackOutlined,
      ClearOutlined,
      CloseCircleOutlined,
      CheckSquareOutlined,
      FileDoneOutlined,
      CheckboxGroup,
      Row,
      Col,
      Checkbox,
      Upload,
      BasicTable,
      TableAction,
      RadioGroup: Radio.Group,
      Radio,
      Input,
      Form,
      FormItem: Form.Item,
      SelectUser,
      Icon,
      UploadOutlined,
      Modal,
      MatchBranchAndUserModal,
      SmartModuleRelateTableDrawer,
      SmartModuleSelDrawer,
      FlowChartDrawer,
      Spin,
      DebugDrawer,
      SmartModuleDrawer: defineAsyncComponent(
        () => import('../smartModule/modules/smartModuleDrawer.vue'),
      ),
      ProcessShowDrawer,
      ProcessSelectDrawer,
      ImpExcel,
      Popconfirm,
      Dropdown,
      Menu,
      MenuItem,
      ProcessViewDrawer,
      CountersignModal,
      ReplyView,
      DistributeModal,
      SelTemplateModal,
      SelStampModal,
      InputPwdModal,
      WritePadModal,
      TipPhraseModal,
      SelDeptModal,
      LocationMarkModal,
      LocationMarkTdModal,
      Progress,
      ProfileOutlined,
      PictureOutlined,
      DownloadOutlined,
      ClockCircleOutlined,
      Tooltip,
      Select,
      SelectOption: Select.Option,
      FileZipOutlined,
      DesignIframe,
      CheckOutlined,
      ProcessTimeLine,
      Tabs,
      TabPane,
      ApprovalProcessLine,
    },
    props: {
      myActionId: {
        type: Number,
        default: 0,
      },
      isInDrawer: {
        type: Boolean,
        default: false,
      },
    },
    emits: ['success', 'register', 'showView', 'closeDrawer', 'launchFlowAction'],
    setup(props, { emit }) {
      const { createMessage, createConfirm, createSuccessModal, createErrorModal } = useMessage();
      const isSpinning = ref(false);
      const content = ref('');
      const common = ref('');
      const srcId = ref('-src');
      const toActions = ref<any>([]);
      const matchJson = ref<any>({});
      const selectDeptCode = ref('');
      const { t } = useI18n();
      const route = useRoute();
      const go = useGo();
      const userStore = useUserStore();
      const cwsId = ref(0);
      const flowIsRemarkShow = ref(false);
      const flowRemarkPos = ref(0);
      const isPlusDescShow = ref(false);
      const { setTitle, closeCurrent } = useTabs();
      const fileList = ref<UploadProps['fileList']>([]);

      const curFormUtil: CurFormUtil | undefined = inject('curFormUtil');
      const { currentRoute, replace, push, resolve } = useRouter();
      const multipleTabStore = useMultipleTabWithOutStore();
      const toolbarClass = ref('toolbar');
      //处理过程和时间线
      const activeTimeKey = ref('1');
      // 发起人选择节点上的人员时间线
      const approvalProcessLineRef = ref<Nullable<HTMLElement>>(null);

      const formRowData = ref<formRowData>({
        cwsWorkflowTitle: '',
        cwsWorkflowResult: '',
        cwsWorkflowLevel: 0,
        levelDesc: '',
        flowId: '',
        starterRealName: '',
        actionId: '',
        myActionId: -1,
        aryButton: [],
        isFlowLevelDisplay: true,
        hasView: false,
        aryView: [],
        isFlowStarted: false,
        isFlowTitleReadonly: true,
        formCode: '',
        isHasAttachment: true,
        isPlusBefore: true,
        isMyPlus: false,
        plusDesc: '',
        isPlus: false,
        isNotShowNextUsers: false,
        isFlowManager: false,
        isReply: false,
        flowStatus: 1, // 流程状态，默认为处理中
        canQuery: false,
        isDebug: false,
        canDelAttachment: false,
        isRemarkShowInProcessList: false,
        officeEditor: '',
        onlyofficeServerUrl: '',
        canEditAttachment: false,
        branchMode: 1, // 分支模式，默认为多选
        isWordDownloadByOfd: 0,
        deptFieldLimited: '',
        deptLimited: '',
      });

      // 导入
      const isImport = ref(false);
      const isDownload = ref(false);
      const btnAgreeName = ref('提交');
      const btnReturnName = ref('退回');
      const btnDisagreeName = ref('拒绝');
      const btnDistributeName = ref('抄送');
      const btnSaveName = ref('保存');
      const btnPlusName = ref('加签');
      const btnDelName = ref('删除');
      const btnTransferName = ref('转办');
      const btnSuspendName = ref('挂起');
      const btnResumeName = ref('恢复');
      const btnDiscardName = ref('放弃');
      const btnFinishAgreeName = ref('结束');
      const btnToReturnerName = ref('直送');
      const btnReadedName = ref('已阅');

      const aryAttSize = ref(0);

      // 发起流程步骤是否正在加载中，为true后使工具条显示，用以加快显示速度，提升用户体验
      const isLaunched = ref(false);
      // 处理流程步骤是否正在加载中，为true后使工具条按钮由灰色变为蓝色，可点击
      const isDoLoading = ref(false);
      // 处理流程步骤的获取流程信息部分（除去filterJS等外）是否已加载，为true后显示全部内容
      const isLoaded = ref(false);
      // 流程表单及赋值脚本加载完毕后为true
      const cwsIsFormLoaded = ref(false);

      const isLoadTimeExceeded = ref(false);

      const serverInfo = userStore.getServerInfo;
      const isObjStoreEnabled = ref(serverInfo.isObjStoreEnabled);
      const isUseBreakpointResume = ref(serverInfo.isUseBreakpointResume);
      let isBtnInitFlow = false;

      // -----------------------------------------------------获取当前流程信息开始-------------------------------------------------------------
      //获取当前流程信息
      let flowProcessData = {} as any;
      async function getFlowProcessContent(
        myActionId: number,
        isGetBranchMatchOnCondFieldChange = true,
      ) {
        // 加载（刷新）前清除自动拉单的interval，以免在刷新时自动拉单，造成已填的数据被刷掉
        try {
          if (cwsGlobalAutoSelIntervalArr) {
            for (let i in cwsGlobalAutoSelIntervalArr) {
              window.clearInterval(cwsGlobalAutoSelIntervalArr[i]);
            }
            window.cwsGlobalAutoSelIntervalArr = [];
          }
        } catch (error) {
          if (error instanceof ReferenceError) {
            // console.log('变量未声明');
            window.cwsGlobalAutoSelIntervalArr = [];
          }
        }

        isDoLoading.value = true;
        console.log('myActionId', myActionId, 'isTab.value', isTab.value);
        initWindowFunc();

        // 清除 interval
        curFormUtil?.clearIntervals();

        isSpinning.value = true;
        let data = await getFlowProcess({ myActionId: myActionId, cwsFormName: getFormName.value });
        // 处理子流程
        if (data.res && data.res == 2) {
          if (data.toDo == 'process' && data.myActionId) {
            formRowData.value.myActionId = data.myActionId;
            data = await getFlowProcess({
              myActionId: data.myActionId,
              cwsFormName: getFormName.value,
            });
          }
        }
        // 服务端canSubmit有异常抛出
        if (data.res && data.res == 1) {
          isSpinning.value = false;
          createMessage.warn(data.msg);
          if (isTab.value) {
            handleClose();
            go({
              path: '/processShow',
              query: {
                flowId: data.flowId,
                title: data.cwsWorkflowTitle,
                isFromProcess: true,
                cacheName: `processShow${data.flowId}`,
              },
            });
          } else {
            // 进入到详情页（抽屉中才能进入到详情页）
            emit('showView', {
              'f.id': data.flowId,
              'f.title': data.cwsWorkflowTitle,
            });
            handleClose();
          }
          return;
        }

        isSpinning.value = false;

        flowProcessData = data;
        aryAttSize.value = data.aryAttSize;
        // common.value = data.script;
        selectDeptCode.value = '';

        // 页面风格
        let cont = data.content;
        let isPageStyleLight = data.isPageStyleLight;
        // if (isPageStyleLight) {
        //   cont = cont.replace('tabStyle_8', 'table-lte');
        // }
        // content.value = cont;

        // setContentHtml(cont, getFormName.value, isPageStyleLight);

        // 清空 isAfterSaveformvalueBeforeXorCondSelect，因为当在生产环境deubg模式运行时，当上一节点为条件分支时，可能会带入isAfterSaveformvalueBeforeXorCondSelect的值为true
        if (fo('isAfterSaveformvalueBeforeXorCondSelect')) {
          fo('isAfterSaveformvalueBeforeXorCondSelect').value = '';
        }

        cwsId.value = data.cws_id;
        flowIsRemarkShow.value = data.flowIsRemarkShow;
        flowRemarkPos.value = data.flowRemarkPos;

        const newMatchJson = data.matchJson || {};
        console.log('getFlowProcessContent data', data);
        handleMatchJson(newMatchJson);

        // 当actions有多行时，自适应toolbar-wrap高度
        console.log('toActions.value.length', toActions.value.length);
        if (toActions.value.length > 1) {
          $('.toolbar-wrap').css('height', 70 + toActions.value.length * 40 + 'px');
        } else {
          $('.toolbar-wrap').css('height', '100px');
        }
        // 当toActions很多，而toolbar仍为fixed，会遮挡屏幕可见区域，甚至完全挡住
        if (toActions.value.length > 3) {
          toolbarClass.value = 'toolbar-too-many';
        }

        formRowData.value = {
          cwsWorkflowTitle: data.flowTitle,
          cwsWorkflowResult: '',
          cwsWorkflowLevel: data.level,
          levelDesc: data.levelDesc,
          flowId: data.flowId,
          actionId: data.actionId,
          myActionId: myActionId,
          starterRealName: data.starterRealName,
          aryButton: data.aryButton,
          isFlowLevelDisplay: data.isFlowLevelDisplay,
          hasView: data.hasView,
          aryView: data.aryView,
          isFlowStarted: data.isFlowStarted,
          isFlowTitleReadonly: data.isFlowTitleReadonly,
          formCode: data.formCode,
          isHasAttachment: data.isHasAttachment,
          isMyPlus: data.isMyPlus,
          isPlusBefore: data.isPlusBefore,
          plusDesc: data.plusDesc,
          isPlus: data.isPlus,
          isNotShowNextUsers: data.isNotShowNextUsers,
          isFlowManager: data.isFlowManager,
          isReply: data.isReply,
          flowStatus: data.flowStatus,
          canQuery: data.canQuery,
          isDebug: data.isDebug,
          canDelAttachment: data.canDelAttachment,
          isRemarkShowInProcessList: data.isRemarkShowInProcessList,
          officeEditor: data.officeEditor,
          onlyofficeServerUrl: data.onlyofficeServerUrl,
          canEditAttachment: data.canEditAttachment,
          branchMode: data.branchMode,
          isWordDownloadByOfd: data.isWordDownloadByOfd,
          deptFieldLimited: data.deptFieldLimited,
          deptLimited: data.deptLimited,
        };
        console.log('formRowData', unref(formRowData));
        console.log('isTab.value', isTab.value);

        if (flowProcessData.aryMyAction && flowProcessData.aryMyAction.length > 0) {
          console.log('flowProcessData.aryMyAction', flowProcessData.aryMyAction);
          console.log('myActionId', myActionId);
          let thisMyAction = flowProcessData.aryMyAction.filter((item) => item.id == myActionId);
          if (thisMyAction && thisMyAction.length > 0)
            formRowData.value.cwsWorkflowResult = thisMyAction[0].result;

          setTableData(flowProcessData.aryMyAction);
        } else {
          setTableData([]);
        }

        if (isTab.value) {
          let title = data.flowId + '-' + data.flowTitle;
          if (title.length > 18) {
            title = title.substring(0, 18) + '...';
          }
          setTitle(title);
        }

        // 如果是我做的加签，且不是前加签，且加签描述不为空
        isPlusDescShow.value =
          formRowData.value.isMyPlus &&
          !formRowData.value.isPlusBefore &&
          formRowData.value.plusDesc.length > 0;

        console.log('aryButton', data.aryButton);
        // 取出同意、退回及拒绝按钮的名称
        for (let k in data.aryButton) {
          let btn = data.aryButton[k];
          if (btn.name === 'commit') {
            btnAgreeName.value = btn.text;
          } else if (btn.name === 'disagree') {
            btnDisagreeName.value = btn.text;
          } else if (btn.name === 'return') {
            btnReturnName.value = btn.text;
          } else if (btn.name == 'distribute') {
            btnDistributeName.value = btn.text;
          } else if (btn.name == 'save') {
            btnSaveName.value = btn.text;
          } else if (btn.name == 'plus') {
            btnPlusName.value = btn.text;
          } else if (btn.name == 'del') {
            btnDelName.value = btn.text;
          } else if (btn.name == 'transfer') {
            btnTransferName.value = btn.text;
          } else if (btn.name == 'suspend') {
            btnSuspendName.value = btn.text;
          } else if (btn.name == 'resume') {
            btnResumeName.value = btn.text;
          } else if (btn.name == 'discard') {
            btnDiscardName.value = btn.text;
          } else if (btn.name == 'finishAgree') {
            btnFinishAgreeName.value = btn.text;
          } else if (btn.name == 'toRetuner') {
            btnToReturnerName.value = btn.text;
          } else if (btn.name == 'readed') {
            btnReadedName.value = btn.text;
          }
        }

        // if (unref(formRowData).isHasAttachment) {
        // 如果附件列表大于0，则置props及刷新附件列表
        setProps({
          searchInfo: {
            flowId: unref(formRowData).flowId,
            actionId: unref(formRowData).actionId,
          },
        });
        reloadAttachment();
        // }

        await nextTick();

        if (!isCached) {
          console.log('processHandleView isCached', isCached);
          return;
        }

        // 加快显示
        isLoaded.value = true;

        // hasApproverSelectByStarter 表示流程中是否有节点上审批人类型为发起者选人
        if (isGetBranchMatchOnCondFieldChange && data.hasApproverSelectByStarter) {
          initContent(true);
        } else {
          initContent(false);
        }
      }

      async function initContent(isGetBranchMatchOnCondFieldChange = true) {
        console.log('initContent start');

        // 防止切换太快，有时内容不能显示
        let cont = flowProcessData.content;
        let isPageStyleLight = flowProcessData.isPageStyleLight;
        // if (isPageStyleLight) {
        //   cont = cont.replace('tabStyle_8', 'table-lte');
        // }
        // content.value = cont;

        setContentHtml(cont, getFormName.value, isPageStyleLight);

        // 加快显示，故把isLoaded置为true，原来在filterJS之后提前到这里
        isLoaded.value = true;

        let rootPath = import.meta.env.VITE_PUBLIC_PATH;
        if (rootPath.endsWith('/')) {
          rootPath = rootPath.substring(0, rootPath.lastIndexOf('/'));
        }

        // 如果存在动态引入的js，则初始化
        if (typeof useFormJsFunc[formRowData.value.formCode] === 'function') {
          const funcs = [handleRefresh];
          useFormJsFunc[formRowData.value.formCode](
            'init("' + formRowData.value.formCode + '")',
            funcs,
          ).then((ret) => {
            console.log('useFormJsFunc["' + formRowData.value.formCode + '"]', ret);
          });
        }

        const url = `${rootPath}/resource/js/form/form_js_${flowProcessData.formCode}.js?pageType=flow&flowId=${flowProcessData.flowId}&myActionId=${flowProcessData.myActionId}&cwsFormName=${getFormName.value}&actionId=${formRowData.value.actionId}`;
        console.log('form_js url', url);
        let script1 = document.createElement('script');
        script1.type = 'text/javascript';
        script1.src = url;
        script1.id = `${100}${srcId.value}`;
        document.getElementsByTagName('head')[0].appendChild(script1);

        // 加载后台事件中配置的前台脚本
        if (flowProcessData.formJs && flowProcessData.formJs.length > 0) {
          try {
            let scriptFormJs = document.createElement('script');
            scriptFormJs.type = 'text/javascript';
            scriptFormJs.text = flowProcessData.formJs;
            scriptFormJs.id = `${101}${srcId.value}`;
            document.getElementsByTagName('head')[0].appendChild(scriptFormJs);
          } catch (e) {
            console.warn(e);
          }
        }

        // 初始化查询侦听
        putParamInFormMap(getFormName.value, 'flowTypeCode', flowProcessData.flowTypeCode);
        putParamInFormMap(getFormName.value, 'queryId', flowProcessData.queryId);
        putParamInFormMap(getFormName.value, 'queryAjaxUrl', flowProcessData.queryAjaxUrl);
        putParamInFormMap(getFormName.value, 'queryCond', flowProcessData.queryCond);
        onQueryRelateFieldChange(getFormName.value);
        initQueryCondListener(getFormName.value);

        await nextTick();

        initFormCtl(getFormName.value);

        // 校验规则
        if (flowProcessData.checkJsSub) {
          try {
            eval(flowProcessData.checkJsSub);
          } catch (e) {
            console.log(e);
          }
        }

        // 为向下兼容，引入服务端form_js
        try {
          await ajaxGetJS(
            `/flow/form_js/form_js_${flowProcessData.formCode}.jsp?pageType=flow&flowId=${flowProcessData.flowId}&myActionId=${flowProcessData.myActionId}&cwsFormName=${getFormName.value}`,
          );
        } catch (e) {
          console.warn(e);
        }

        // 异步获取显示规则等脚本
        if (flowProcessData.isRendWithoutViewRule) {
          getFlowProcessScript({
            actionId: formRowData.value.actionId,
            cwsFormName: getFormName.value,
            pageType: 'flow',
          }).then((res) => {
            console.log('getFlowProcessScript filterJS');
            filterJS(res.script, srcId.value, getFormName.value);
          });
        }

        console.log('initContent filterJS');
        if (!o(getFormName.value)) {
          console.warn('Form: ' + getFormName.value + ' is not found, may be the tab is switched');
          return;
        }

        // await filterJS(flowProcessData.content, srcId.value, getFormName.value);

        cwsIsFormLoaded.value = true;
        // 表单加载完成事件
        eventTarget.fireEvent({
          type: EVENT_TYPE.FORM_LOADED,
          flowId: formRowData.value.flowId,
          actionId: formRowData.value.actionId,
          id: cwsId.value,
          cwsFormName: getFormName.value,
          attachments: attachments.value,
        });

        setTimeout(async () => {
          // 初始化日期控件
          initDatePicker();

          // 初始化计算控件
          initCalculator();

          loadImg('flowForm');

          // 初始化表单中指定的人员和限定部门字段的侦听，不能用change事件，因为可能为表单域选择宏控件映射的字段
          let bindFieldList: string[] = flowProcessData.bindFieldList;
          console.log('bindFieldList', bindFieldList);
          let bindFieldListOldVal: Array<string> = new Array<string>();
          for (let k in bindFieldList) {
            let fieldName = bindFieldList[k];
            bindFieldListOldVal[k] = '';
            curFormUtil?.setInterval(function () {
              // console.log('fo(' + fieldName + ')', fo(fieldName));
              if (
                fo(fieldName, getFormName.value) &&
                bindFieldListOldVal[k] != fo(fieldName, getFormName.value).value
              ) {
                console.log(
                  'bindFieldListOldVal[' + k + ']',
                  bindFieldListOldVal[k],
                  'fo(fieldName, getFormName.value).value',
                  fo(fieldName, getFormName.value).value,
                );
                reMatchUser(fieldName, fo(fieldName, getFormName.value).value);
                bindFieldListOldVal[k] = fo(fieldName, getFormName.value).value;
              }
            }, 500);
          }

          // 如果是开始节点，则获取条件字段，以便于匹配条件，获得后续节点以选择人员
          if (!formRowData.value.isFlowStarted && flowProcessData?.matchJson?.hasCond) {
            let condFields = await getFieldNamesInCond({ actionId: formRowData.value.actionId });
            console.log('condFields', condFields);
            condFields.forEach((item) => {
              console.log('tagName', fo(item).tagName);
              if (fo(item).tagName == 'INPUT' && fo(item).getAttribute('type') == 'radio') {
                $('input[name=' + item + ']').click(function () {
                  console.log('condField ' + item, $(this).val());
                  getBranchMatchOnCondFieldChange();
                });
              } else {
                $(fo(item)).change(function () {
                  console.log('condField ' + item, fo(item).value);
                  getBranchMatchOnCondFieldChange();
                });
              }
            });
          }
        }, 100);

        // if (flowProcessData?.matchJson?.hasCond) {
        if (isGetBranchMatchOnCondFieldChange) {
          // 区配条件
          getBranchMatchOnCondFieldChange();
        }
        // }

        fetchPhrases();

        generateTab();

        // 使最长3秒，顶部的提交按钮可用，以免网络不佳的时候使得onRendEnd延迟
        setTimeout(() => {
          isLoadTimeExceeded.value = true;
        }, 3000);
      }

      const matchBranchAndUserToActions = ref([]);
      const matchBranchAndUserActions = ref([]);
      let matchBranchAndUserParams = {};
      // 当条件中的字段变化时，重新匹配分支以便于发起者选人
      async function getBranchMatchOnCondFieldChange() {
        fo('op').value = 'saveformvalue';
        matchBranchAndUserToActions.value = [];
        matchBranchAndUserActions.value = [];
        isSpinning.value = true;
        await getFinishAction(getFormData())
          .then((res) => {
            isSpinning.value = false;
            if (res.code == 500) {
              createErrorModal({
                title: t('common.tip'),
                content: () => h('pre', res.msg),
                okText: '关闭',
                width: '550px',
              });

              return;
            }
          })
          .catch((error) => {
            createMessage.error(error.msg);
            isSpinning.value = false;
          });

        // 判断如果表单中带有文件控件，则刷新
        let form = new FormData(o(getFormName.value));
        for (var key of form.keys()) {
          // 如果是文件上传控件
          if (fo(key).type == 'file') {
            // 刷新，否则会导致保存多次草稿，文件组宏控件出现重复上传
            refreshForm(false);
            break;
          }
        }

        isSpinning.value = true;
        matchBranchAndUserParams = {
          op: 'matchNextBranch',
          actionId: flowProcessData.actionId,
          deptOfUserWithMultiDept: selectDeptCode.value, // 当前所选的部门
          myActionId: flowProcessData.myActionId,
          askType: 1,
          isMatchForStarterSelUser: true, // 为发起者选择用户而匹配条件分支
        };
        getMatchBranchAndUserData();
        return;
      }

      const refreshForm = (isGetBranchMatchOnCondFieldChange = true) => {
        // 刷新
        fileList.value = [];
        $('#content_' + getFormName.value).html('');
        getFlowProcessContent(unref(formRowData).myActionId, isGetBranchMatchOnCondFieldChange);
      };

      const getMatchBranchAndUserData = () => {
        getMatchBranchAndUser(matchBranchAndUserParams).then(async (res) => {
          isSpinning.value = false;
          console.log('getMatchBranchAndUser res', res);
          if (res.data.errCode == -2) {
            // 不需要显示info
            return;
          } else if (res.data.errCode == -1) {
            // 如果条件不满足，在默认条件分支中匹配用户matchActionUser报错
            // createMessage.error(res.data.info);
            console.log(res.data.info);
            return;
          } else if (res.data.errCode == -3) {
            // 条件****不匹配，请注意填写是否正确，重新填写后请点击提交按钮！
            // createMessage.error(res.data.info);
            console.log(res.data.info);
            return;
          }

          var isMatchUserException = false;
          if (res.data.hasOwnProperty('isMatchUserException')) {
            isMatchUserException = res.data.isMatchUserException;
          }

          if (!isMatchUserException) {
            if (res.data.toActions && res.data.toActions.length > 0) {
              matchBranchAndUserToActions.value = res.data.toActions || [];
              let actionId = res.data.toActions[0].id;
              let actions = await getActionsOnBranch({ actionId: actionId });
              matchBranchAndUserActions.value = actions;
              console.log('getActionsOnBranch', actions);
            }

            handleMatchJson(res.data || {});
          }
        });
      };

      async function runConnector(code) {
        let data = await getRunConnector({
          code,
          actionId: formRowData.value.actionId,
          isByRequest: true,
        });
        console.log('runConnector', data);
        if (data.res == 0) {
          let result = data.result;
          // 赋值给表单中的字段
          if (result) {
            for (let k in result) {
              let json = result[k];
              if (fo(json.name)) {
                fo(json.name).value = json.value;
              } else {
                console.log('表单中未到到query中设定的字段:' + json.name);
              }
            }
          }
        }
      }

      function generateTab() {
        // 检查其中是否有多个table
        let $cont = $('form[formCode=' + formRowData.value.formCode + ']').find('#contentBox');
        let $contForm = $('form[formCode=' + formRowData.value.formCode + ']').find(
          `#content_${getFormName.value}`,
        );
        // 找出带有tabTitle的表格
        console.log('$cont', $cont[0]);
        const tabCount = $cont.find('[isTab="true"]').length;
        console.log('tabCount', tabCount);

        if (tabCount >= 1) {
          let $formTab = $cont.find('.form-tab');
          if (!$formTab[0]) {
            $cont.prepend(
              '<div class="form-tab"><div class="form-tab-menu"><ul></ul></div><div class="form-tab-box"></div></div>',
            );
          }

          let $ul = $cont.find('.form-tab').find('ul');
          let $box = $cont.find('.form-tab-box');

          $cont.find('[isTab=true]').each(function (index) {
            let tabTitle = $(this).attr('tabTitle');
            // 检查表格是否已在form-tab中
            // $formTab.find('table[tabTitle=' + $(this).attr('tabTitle') + ']').remove();

            $ul.append('<li id="' + tabTitle + '">' + $(this).attr('tabTitle') + '</li>');
            // $ul.children('li').eq(index).text($(this).attr('tabTitle'));

            $box.append('<div></div>');
            $box.children('div').eq(index).append(this);
          });

          // 加入主表
          $ul.prepend('<li id="mainForm">' + flowProcessData.formName + '</li>');
          $box.prepend('<div></div>');
          $box.children('div').eq(0).append($contForm[0]);

          $('.form-tab-menu li').click(function () {
            //通过 .index()方法获取元素下标，从0开始，赋值给某个变量
            let _index = $(this).index();
            //让内容框的第 _index 个显示出来，其他的被隐藏
            $('.form-tab-box > div').eq(_index).show().siblings().hide();
            //改变选中时候的选项框的样式，移除其他几个选项的样式
            $(this).addClass('form-tab-active').siblings().removeClass('form-tab-active');
          });

          $('.form-tab-menu ul li:first-child').addClass('form-tab-active');
        }
      }

      // 强制在渲染的脚本执行完后，使工具条按钮可用，以免中间有脚本错误，显示不全，但仍能提交
      function onRendEnd(flowId, formCode) {
        if (formRowData.value.flowId == flowId) {
          isDoLoading.value = false;
          console.log(
            'onRendEnd flowId=' +
              flowId +
              ' formCode=' +
              formCode +
              ', isDoLoading is setted to false.',
          );
        } else {
          console.log('onRendEnd ' + formCode);
        }
      }

      // 当表单中的用户有变化时，重新匹配用户
      function reMatchUser(fieldName, fieldValue) {
        let params = {
          op: 'reMatchUser',
          actionId: flowProcessData.actionId,
          myActionId: flowProcessData.myActionId,
          fieldName: fieldName,
          fieldValue: fieldValue,
        };

        getMatchBranchAndUser(params).then((res) => {
          if (res.code === 200) {
            handleMatchJson(res.data || {});
          } else {
            createMessage.warn(res.msg);
          }
        });
      }

      // 取得常用语
      const fetchPhrases = () => {
        getPhrases({}).then((data) => {
          $('.phraseIcon').html(data.tipHtml);
        });
      };

      // ---------------------------------获取当前流程信息结束-----------------------------------------

      // -------------------------------------处理支线开始-----------------------------
      //处理人员匹配结果
      function handleMatchJson(obj) {
        matchJson.value = obj || {};
        if (obj.errCode === -1) {
          createMessage.error(obj.info);
        }
        toActions.value = [];
        if (matchJson.value.toActions && matchJson.value.toActions.length > 0) {
          matchJson.value.toActions.forEach((item) => {
            toActions.value.push({
              ...item,
              deptOfUserWithMultiDept: unref(matchJson).deptOfUserWithMultiDept,
              errCode: unref(matchJson).errCode,
              flagXorRadiate: unref(matchJson).flagXorRadiate,
              hasCond: unref(matchJson).hasCond,
              info: unref(matchJson).info,
              /* isBtnSelUserShow: matchJson.isBtnSelUserShow, */
              isMatchUserException: unref(matchJson).isMatchUserException,
              op: unref(matchJson).op,
              checkers:
                (item.checkers && item.checkers.length > 0
                  ? item.checkers.map((el) => {
                      let isDisabled = false;
                      if (el.hasOwnProperty('disabled')) {
                        isDisabled = el.disabled;
                      }
                      if (!el.hasOwnProperty('checked')) {
                        el.checked = false;
                      } else {
                        el.checked = !!el.checked; // el.checked可能为''
                      }
                      return {
                        ...el,
                        disabled: isDisabled,
                        value: el.userName,
                      };
                    })
                  : []) || [],
              xorChecked:
                item.checkers && item.checkers.length > 0
                  ? item.checkers.some((v) => (v.checked == true ? true : false))
                  : false,
            });
          });
        }
      }

      //设置支线是否勾选人员，如果选中则默认选中当前支线
      function checkXOR(actionId, checker, itemIndex) {
        if (!checker.hasOwnProperty('clickXor')) {
          return;
        }
        var xorObj = document.getElementById('XOR' + actionId);
        if (xorObj == null) return;

        // 如果用户原来未被勾选上，点击后则被勾选上了，置xor控件标志为checked
        if (!checker.checked) {
          // $(xorObj).prop('checked', true); // 无效
          toActions.value[itemIndex].xorChecked = true;
          return;
        } else {
          // click事件优先，此时checker.checked仍为true，需手动改过来，以便于判断 isAllUnchecked
          checker.checked = false;
        }

        // 判断如果该action中所有的用户都未选，则置xor控件标志为checked=false
        var isAllUnchecked = true;
        if (toActions.value[itemIndex].checkers.some((item) => !!item.checked)) {
          isAllUnchecked = false;
        }

        console.log('checker', checker, 'isAllUnchecked', isAllUnchecked);
        if (isAllUnchecked) {
          toActions.value[itemIndex].xorChecked = false;
        }
      }
      // 当存在兼职的情况，选择部门时
      function onSelDept() {
        var params = {
          op: 'matchAfterSelDept',
          actionId: unref(formRowData).actionId,
          myActionId: unref(formRowData).myActionId,
          deptOfUserWithMultiDept: unref(selectDeptCode),
        };
        getMatchBranchAndUser(params).then((res) => {
          if (res.code === 200) {
            handleMatchJson(res.data || {});
          } else {
            createMessage.warn(res.msg);
          }
        });
      }
      // -----------------------------------------------------处理支线结束-------------------------------------------------------------

      // -----------------------------------------------------选择人员开始-------------------------------------------------------------
      // 是否在表单中选择用户标志位
      let isSelUserInForm = false;
      let currentIndex = ref(0);
      let currentActionId = ref(0);
      let currentIsBtnXor = false;
      function selectUser(action, index, isBtnXor) {
        isSelUserInForm = false;
        currentActionId.value = action.id;
        currentIndex.value = index;
        currentIsBtnXor = isBtnXor;
        let users = [];
        console.log('selectUser action', action);
        if (action.checkers && action.checkers.length > 0) {
          // 当节点上设置了角色，但还可以选择用户时，角色中的用户，不带有SelectUser中需用到的name和key值，需补充上，否则在返回时，这两个值就会为undefined
          users = action.checkers.map((item) => {
            return {
              ...item,
              name: item.value || item.userName,
              key: item.value || item.userName,
            };
          });
        }
        console.log('selectUser', { users, checkers: action.checkers });

        // 限定部门、限定部门表单域
        let deptLimited = formRowData.value.deptLimited;
        deptLimited = deptLimited || '';
        if (formRowData.value.deptFieldLimited) {
          let df = fo(formRowData.value.deptFieldLimited).value;

          if (deptLimited == '') deptLimited = df;
          else deptLimited += ',' + df;

          // 转为数组并去重
          let deptAry = deptLimited.split(',');
          deptAry = deptAry.filter(function (item, index) {
            return deptAry.indexOf(item) === index;
          });
          deptLimited = deptAry.join(',');
        }

        openModal(true, {
          isUpdate: false,
          users: users,
          limitDepts: deptLimited,
        });
      }
      // 在表单中选择用户
      let curObjName = '';
      let curUserSelType = 0;
      function selectUserInForm(objName: string, users: any, type = 0, limitDepts: string) {
        isSelUserInForm = true;
        curUserSelType = type;
        curObjName = objName;
        openModal(true, { users, type, limitDepts });
      }

      let isTransfer = false;
      //人员组件选择后回调
      async function handleCallBack(data) {
        console.log('handleCallBack', data);
        if (isTransfer) {
          console.log('names', data[0].name);
          isTransfer = false;
          let params = {
            myActionId: unref(formRowData).myActionId,
            toUserName: data[0].name,
          };
          isSpinning.value = true;
          await transfer(params).then((data) => {
            isSpinning.value = false;

            createConfirm({
              iconType: 'success',
              title: () => h('span', t('common.prompt')),
              content: () => h('span', t('common.opSuccess')),
              maskClosable: false,
              closable: false,
              cancelText: '',
              onOk: async () => {
                handleClose();
              },
            });
          });
          return;
        }

        if (isSelUserInForm) {
          let realNames = data.map((item) => item.realName).join();
          let names = data.map((item) => item.name).join();
          if (fo(curObjName)) {
            console.log('curObjName', curObjName);
            fo(curObjName).value = names;
            fo(curObjName + '_realshow').value = realNames;

            // flow_js.js中调用，用于映射
            try {
              onUserSelectDone(curObjName, names, realNames, curUserSelType);
            } catch (e) {
              console.log('Function: onUserSelectDone is not exist.');
            }
          } else {
            console.warn(curObjName + '不存在');
          }
        } else {
          let datas = data;
          datas.forEach((item) => {
            item.value = item.name;
            item.userName = item.name;
            item.checked = item.checked || true;
            item.id = currentActionId.value;
            item.type = 'checkbox';
            item.disabled = item.disabled || false;
            item.clickXor = item.clickXor || true;
          });

          // 不仅条件分支，不带条件时，也需将xorChecked设为true
          // if (currentIsBtnXor) {
          toActions.value[currentIndex.value].xorChecked = true;
          // }

          toActions.value[currentIndex.value].checkers = [
            // ...toActions.value[currentIndex.value].checkers,
            ...datas,
          ];
        }
      }
      // -----------------------------------------------------选择人员结束-------------------------------------------------------------

      function handleTransfer() {
        isTransfer = true;
        openModal(true, { type: 0 });
      }

      // -----------------------------------------------------表单保存开始-------------------------------------------------------------
      //保存
      async function saveDraft(e, isAfterOnlyofficeSave = false) {
        if (
          !isUploadFinished(currentRoute.value?.query?.titleName || currentRoute.value?.meta?.title)
        ) {
          createMessage.warn('文件正在上传中，请在文件上传结束后再操作');
          return;
        }

        try {
          ctlOnBeforeSerialize(getFormName.value);
        } catch (e) {
          console.info('Function: ctlOnBeforeSerialize is not found');
        }

        isSpinning.value = true;
        await nextTick();

        // onlyoffice保存文件
        if (typeof handleOnlyofficeSave == 'function') {
          if (!isAfterOnlyofficeSave) {
            handleOnlyofficeSave(getFormName.value, 0);
            return;
          }
        }

        // 填报表单很大时，getFormData循环时间长，isSpinning会不显示，所以改为setTimeout
        setTimeout(async () => {
          fo('op').value = 'saveformvalue';
          const form = getFormData();
          await getFinishAction(form).then(async (res) => {
            isSpinning.value = false;
            if (res.code == 500) {
              createMessage.warn(res.msg);
            } else {
              refreshForm(true);
              createMessage.success(res.msg);
            }
          });
        }, 20);
      }
      // -----------------------------------------------------表单保存结束-------------------------------------------------------------

      // -----------------------------------------------------表单提交开始-------------------------------------------------------------
      //提交
      async function toolbarSubmit(e, isInitFlowByBtn = false, isAfterOnlyofficeSave = false) {
        isBtnInitFlow = isInitFlowByBtn;
        console.log('isInitFlowByBtn', isInitFlowByBtn);

        if (typeof ctlOnBeforeSerialize == 'function') {
          try {
            // 用于给ACEEditor赋值
            ctlOnBeforeSerialize(getFormName.value);
          } catch (e) {
            console.error(e);
          }
        } else console.info('Function: ctlOnBeforeSerialize is not found');

        // 检查发起人应选择人员的节点是否已选择
        if (approvalProcessLineRef.value) {
          let isActionUserSelected = approvalProcessLineRef.value.checkActionUserSelected();
          if (!isActionUserSelected) {
            createMessage.warn('请选择节点上的人员');
            return;
          }
        }

        // 摧毁LiveValidation校验，如不摧毁，在massValidate后，会形成重复校验
        var liveOp = new LiveValidation('op');
        LiveValidation.destroyValidate(liveOp.formObj.fields);
        // 除文件、文件组、可视化上传、手写板控件为了必填效果所加的*号外均删除
        $('.LV_presence').each(function () {
          if (!$(this).hasClass('LV_feign')) {
            $(this).remove();
          }
        });

        console.log('toolbarSubmit checkJsSub');
        // 重新生成LiveValidation校验规则
        if (flowProcessData.checkJsSub) {
          try {
            eval(flowProcessData.checkJsSub);
          } catch (e) {}
        }

        // 进行LiveValidation校验
        liveOp = new LiveValidation('op');
        console.log('toolbarSubmit massValidate');
        if (!LiveValidation.massValidate(liveOp.formObj.fields)) {
          let liveErrMsg = LiveValidation.liveErrMsg.replaceAll('<br/>', '\n');
          if (liveErrMsg.indexOf('\n') >= 0 && liveErrMsg.indexOf('\n') != liveErrMsg.length - 1) {
            createMessage.warn({
              content: () => h('pre', liveErrMsg),
              duration: 5,
            });
          } else {
            createMessage.warn(liveErrMsg, 5);
          }
          return;
        }

        // 填报表格的有效性检查
        let isNestCellValid = true;
        let tbs = $('table[id^=nestTable_][hasCalcFields]');
        let tbLen = tbs.length;
        if (tbLen > 0) isNestCellValid = false;
        for (var k = 0; k < tbLen; k++) {
          let id = $(tbs[k]).attr('id') || '';
          let nestFieldName = id.substring('nestTable_'.length);
          console.log('nestTableName hasCalcFields', nestFieldName);
          try {
            isNestCellValid = checkNestTable(nestFieldName);
            if (!isNestCellValid) {
              return;
            }
          } catch (e) {
            console.warn('checkNestTable is not found.');
          }
        }
        if (!isNestCellValid) return;

        // 重新生成LiveValidation校验规则
        // if (flowProcessData.checkJsSub) {
        //   try {
        //     eval(flowProcessData.checkJsSub);
        //   } catch (e) {
        //     console.log(e);
        //   }
        // }

        if (typeof onFormSubmit == 'function') {
          try {
            // 用于在form_js中进行校验
            let re = onFormSubmit(getFormName.value, 'flow');
            if (!re) {
              return;
            }
          } catch (e) {
            console.error(e);
          }
        } else console.info('Function: onFormSubmit is not found');

        // onlyoffice保存文件
        if (typeof handleOnlyofficeSave == 'function') {
          if (!isAfterOnlyofficeSave) {
            if (handleOnlyofficeSave(getFormName.value, 1)) return;
          }
        }

        var canUserStartFlow = flowProcessData.canUserStartFlow;
        createConfirm({
          iconType: 'warning',
          title: () => h('span', t('common.prompt')),
          content: () => h('span', canUserStartFlow ? '您确定要开始流程么？' : '您确定要提交么？'),
          onOk: async () => {
            isSpinning.value = true;
            await submitResult();
            isSpinning.value = false;
          },
        });
      }

      async function submitResult(
        isAfterSaveformvalueBeforeXorCondSelect?,
        actions = [],
        isToReturner?,
      ) {
        if (
          !isUploadFinished(currentRoute.value?.query?.titleName || currentRoute.value?.meta?.title)
        ) {
          createMessage.warn('文件正在上传中，请在文件上传结束后再操作');
          return;
        }

        console.log(
          'submitResult isAfterSaveformvalueBeforeXorCondSelect',
          isAfterSaveformvalueBeforeXorCondSelect,
        );
        let hasCond = flowProcessData?.matchJson?.hasCond;
        console.log(
          'submitResult hasCond',
          hasCond,
          'flowProcessData?.matchJson',
          flowProcessData?.matchJson,
        );
        let isAutoSaveArchive = flowProcessData.isAutoSaveArchive;
        console.log('submitResult isToReturner', isToReturner);
        if (isToReturner == null || !isToReturner) {
          if (hasCond && !isAfterSaveformvalueBeforeXorCondSelect) {
            // 先ajax保存表单，然后再ajax弹出对话框选择用户，然后才交办
            fo('op').value = 'saveformvalueBeforeXorCondSelect';

            isSpinning.value = true;
            await getFinishAction(getFormData(actions))
              .then((res) => {
                isSpinning.value = false;
                if (res.code == 500) {
                  createErrorModal({
                    title: t('common.tip'),
                    content: () => h('pre', res.msg),
                    okText: '关闭',
                    width: '550px',
                  });
                  return;
                }

                // createMessage.success(res.msg);
                showResponse(res);
              })
              .catch((error) => {
                createMessage.error(error.msg);
              });

            return;
          }
        } else {
          fo('flowAction', getFormName.value).value = 'toRetuner';
        }

        // 如果是自动存档节点，则先保存表单，然后回到此页面，在onload的时候再FinishActoin
        if (isAutoSaveArchive) {
          fo('op').value = 'AutoSaveArchiveNodeCommit';
        } else {
          fo('op').value = 'finish';
        }

        isSpinning.value = true;

        isAfterSaveformvalueBeforeXorCondSelect = !!isAfterSaveformvalueBeforeXorCondSelect;
        if (isAfterSaveformvalueBeforeXorCondSelect) {
          fo('isAfterSaveformvalueBeforeXorCondSelect').value = 'true';
        } else {
          fo('isAfterSaveformvalueBeforeXorCondSelect').value = 'false';
        }
        console.log(
          "fo('isAfterSaveformvalueBeforeXorCondSelect').value",
          fo('isAfterSaveformvalueBeforeXorCondSelect').value,
        );

        let formData = getFormData(actions);
        // getFormData中返回null，说明在取form data数据的时候，有报错
        if (formData == null) return;

        await getFinishAction(formData)
          .then((res) => {
            isSpinning.value = false;
            if (res.code == 500) {
              createErrorModal({
                title: t('common.tip'),
                content: () => h('pre', res.msg),
                okText: '关闭',
                width: '550px',
              });

              // if (res.msg.indexOf('\n') >= 0 && res.msg.indexOf('\n') != res.msg.length - 1) {
              //   // 使支持通过\n换行
              //   createMessage.warn({
              //     content: () => h('pre', res.msg),
              //   });
              // } else {
              //   createMessage.warn(res.msg);
              // }
              return;
            }
            // 此处不需要显示操作成功信息，否则可能会与对话框中的信息重复
            // createMessage.success(res.msg);
            showResponse(res);
          })
          .catch((e) => createMessage.warning(e.msg));
      }

      async function showResponse(data) {
        if (data == null) {
          createMessage.warning('返回数据为空');
          return;
        }

        // // 过滤掉其它字符，只保留JSON字符串
        // var m = data.match(/\{.*?\}/gi);
        // if (m != null) {
        //   if (m.length == 1) {
        //     data = m[0];
        //   }
        // }

        // try {
        //   data = jQuery.parseJSON(data);
        // } catch (e) {
        //   createMessage.warning(data);
        //   return;
        // }

        if (data.ret == '0') {
          createErrorModal({
            title: t('common.tip'),
            content: () => h('pre', data.msg),
            okText: '关闭',
            width: '550px',
          });
          // createMessage.error(data.msg);
          return;
        }

        let isDebug = flowProcessData.isDebug;
        var op = data.op;
        if (op === 'read') {
          if (isDebug) {
            // layer.alert(data.msg, {
            //     btn: ['确定'],
            //     yes: function() {
            //         window.location.href = "flow/flow_list_debugger.jsp?myActionId=[(${myActionId})]";
            //     }
            // });
            createConfirm({
              iconType: 'success',
              title: () => h('span', t('common.prompt')),
              content: () => h('span', data.msg),
              maskClosable: false,
              closable: false,
              cancelText: '',
              onOk: () => {
                handleClose();
                go({
                  path: '/flowDebug',
                  query: {
                    myActionId: flowProcessData.myActionId,
                    flowId: flowProcessData.flowId,
                  },
                });
              },
            });
          } else {
            done(data.msg, true, _);
          }
          return;
        } else if (op == 'saveformvalue') {
          createMessage.info(data.msg);
          fileList.value = [];
          reloadAttachment();
          return;
        } else if (op == 'AutoSaveArchiveNodeManualFinish') {
          // 20200428自动存档已经不需要再回到flow_dispose.jsp页面处理了
          done(data.msg, true, _);
          return;
        } else if (op == 'manualFinish' || op == 'manualFinishAgree') {
          done(data.msg, true, _);
        } else if (op == 'finish') {
          // 当流程处理后在form_js_表单编码.jsp文件中调用
          if (typeof onFinishAction === 'function') {
            onFinishAction(op);
          }

          var isCustomRedirectUrl = flowProcessData.isCustomRedirectUrl;
          if (isCustomRedirectUrl) {
            go({
              path: flowProcessData.redirectUrl,
              query: {
                myActionId: flowProcessData.myActionId,
                flowId: flowProcessData.flowId,
              },
            });
          } else {
            var nextMyActionId = data.nextMyActionId;
            if (nextMyActionId != '') {
              createConfirm({
                iconType: 'success',
                title: () => h('span', t('common.prompt')),
                content: () => h('span', data.msg),
                maskClosable: false,
                closable: false,
                cancelText: '',
                onOk: async () => {
                  await getFlowProcessContent(nextMyActionId);
                },
                onCancel: async () => {
                  handleClose();
                },
              });
            } else {
              console.log('isDebug', isDebug);
              if (isDebug) {
                let isDebugCache = getIsDebug();
                if (isDebugCache == 'true') {
                  go({
                    path: '/flowDebugPage',
                    query: {
                      myActionId: flowProcessData.myActionId,
                      flowId: flowProcessData.flowId,
                    },
                  });
                } else {
                  userStore.setIsDebug('false');
                  handleClose();
                  go({
                    path: '/flowDebug',
                    query: {
                      myActionId: flowProcessData.myActionId,
                      flowId: flowProcessData.flowId,
                    },
                  });
                }
              } else {
                done(data.msg, false, op);
              }
            }
          }
        } else if (op == 'return') {
          if (isDebug) {
            let isDebugCache = getIsDebug();
            if (isDebugCache == 'true') {
              go({
                path: '/flowDebugPage',
                query: {
                  myActionId: flowProcessData.myActionId,
                  flowId: flowProcessData.flowId,
                },
              });
            } else {
              userStore.setIsDebug('false');
              handleClose();
              go({
                path: '/flowDebug',
                query: {
                  myActionId: flowProcessData.myActionId,
                  flowId: flowProcessData.flowId,
                },
              });
            }

            // 置刷新标志
            multipleTabStore.updateIsRefreshProcessPage(true);
          } else {
            done(data.msg, true, '');
          }
        } else if (op == 'saveformvalueBeforeXorCondSelect') {
          const params = {
            op: 'matchNextBranch',
            actionId: flowProcessData.actionId,
            deptOfUserWithMultiDept: selectDeptCode.value, // 当前所选的部门
            myActionId: flowProcessData.myActionId,
            askType: 1,
          };
          getMatchBranchAndUser(params).then((res) => {
            console.log('getMatchBranchAndUser res', res);
            if (res.data.errCode == -2) {
              // 不需要显示info
              return;
            } else if (res.data.errCode == -1) {
              // 如果条件不满足，在默认条件分支中匹配用户matchActionUser报错
              createMessage.error(res.data.info);
              return;
            } else if (res.data.errCode == -3) {
              // 条件****不匹配，请注意填写是否正确，重新填写后请点击提交按钮！
              createMessage.error(res.data.info);

              // 判断如果表单中带有文件控件，则刷新
              let form = new FormData(o(getFormName.value));
              for (var key of form.keys()) {
                // 如果是文件上传控件
                if (fo(key).type == 'file') {
                  // 刷新，否则当条件未匹配成功，再次提交会导致文件组宏控件出现重复上传
                  refreshForm(false);
                  break;
                }
              }
              return;
            }

            var rendResult = ref('');
            // 判断有没有匹配到人员
            let hasUserCheckbox = res.data.toActions
              ? res.data.toActions.some((item) => item.checkers && item.checkers.length > 0)
              : false;

            var isMatchUserException = false;
            if (res.data.hasOwnProperty('isMatchUserException')) {
              isMatchUserException = res.data.isMatchUserException;
            }
            console.log(
              'hasUserCheckbox',
              hasUserCheckbox,
              'isBtnSelUserShow',
              res.data.isBtnSelUserShow,
              'isMatchUserException',
              isMatchUserException,
            );
            // 如果没有匹配到用户，且不存在自选用户，且没有匹配异常，且条件匹配，说明可能是用了辅助角色，直接提交
            if (
              !hasUserCheckbox &&
              !res.data.isBtnSelUserShow &&
              !isMatchUserException &&
              res.data.errCode != -3 // 条件不匹配
            ) {
              console.log('res.data', res.data);
              // 对分支匹配结果进行处理，存入toActions
              handleMatchJson(res.data);
              // 如果toActions中仅匹配到一条分支（且只应匹配到一条分支），需置xorChecked为true，以便于在submitResult中getFormData时，将xorChecked的分支作为XorNextActionInternalNames提交
              if (toActions.value.length == 1) {
                toActions.value[0].xorChecked = true;
              }
              submitResult(true, toActions);
              return;
            }
            console.log('hasUserCheckbox', hasUserCheckbox);
            // 如果匹配到人员、没有“选择用户”按钮且条件匹配
            if (
              hasUserCheckbox &&
              !res.data.isBtnSelUserShow &&
              !isMatchUserException &&
              res.data.errCode != -3 // 条件不匹配
            ) {
              rendResult.value = '如果不需要选择用户，请直接点击确定按钮！';
              // 判断是否存在未被disabed的用户，即需手动勾选的用户
              let hasCheckerNotDisabled = res.data.toActions.some((item) => {
                if (item.checkers && item.checkers.length > 0) {
                  for (let k in item.checkers) {
                    if (!item.checkers[k].hasOwnProperty('disabled')) {
                      return true;
                    }
                  }
                } else {
                  // 如果是自选用户
                  if (item.isBtnSelUser) {
                    return true;
                  }
                }
                return false;
              });

              console.log('hasCheckerNotDisabled', hasCheckerNotDisabled);

              // 如果所有的用户均是disabled则直接提交
              if (!hasCheckerNotDisabled) {
                handleMatchJson(res.data);
                submitResult(true);
                return;
              }
            }

            var isNotShowNextUsers = flowProcessData.isNotShowNextUsers;
            if (isNotShowNextUsers) {
              if (!isMatchUserException) {
                // 直接提交
                rendResult.value = '请点击确定按钮';
                submitResult(true);
                return;
              }
            }

            openMatchJsonModal(true, {
              record: res,
              rendResult: unref(rendResult),
              formRowData: unref(formRowData),
            });
          });
        }
      }
      //打开分支线人员弹窗
      const [matchJsonRegisterModal, { openModal: openMatchJsonModal }] = useModal();
      //分支线人员弹窗回调
      function handleMatchJsonCallBack(actions) {
        submitResult(true, actions);
      }
      function done(msg, isClose, op) {
        // 置刷新标志
        multipleTabStore.updateIsRefreshProcessPage(true);
        console.log('done isBtnInitFlow', isBtnInitFlow);

        if (isBtnInitFlow) {
          // 通过表单中的按钮发起流程
          initFlowByBtn();
          return;
        }

        console.log('op', op, 'isClose', isClose);
        if (isClose) {
          createConfirm({
            iconType: 'success',
            title: () => h('span', t('common.prompt')),
            content: () => h('span', msg),
            maskClosable: false,
            closable: false,
            cancelText: '',
            onOk: async () => {
              handleClose();
            },
          });
        } else {
          // 当操作为“提交”时
          if ('finish' == op) {
            var isRecall = flowProcessData.isRecall;
            console.log('isRecall', isRecall);
            // 如果能够撤回
            if (isRecall) {
              // msg += ' 如果数据填写有误，请及时撤回';

              // createMessage.success(msg);
              // // 进入到详情页
              // emit('showView', { 'f.id': flowProcessData.flowId });

              createSuccessModal({
                title: t('common.tip'),
                content: msg,
                onOk: () => {
                  // 进入到详情页（抽屉中才能进入到详情页）
                  emit('showView', {
                    'f.id': flowProcessData.flowId,
                    'f.title': formRowData.value.cwsWorkflowTitle,
                  });
                  handleClose();
                },
              });
            } else {
              // createMessage.success(msg);

              createSuccessModal({
                title: t('common.tip'),
                content: msg,
                onOk: () => {
                  handleClose();
                },
              });
            }

            // handleClose();
          }
        }
      }

      //封装基本FormData 可基于返回FormData xx.append()附加参数
      function getFormData(matcBranchAndUsertoActions = []) {
        // let form = new FormData($('#flowForm')[0]);
        let form = new FormData(o(getFormName.value));

        let cwsHiddenFields = '';
        let arr = [];
        let arrNest = [];
        let k = 0,
          j = 0;
        // FormData中只能取到第一个文件，需删除掉，得取dropFiles
        for (var key of form.keys()) {
          // console.log('key:', key, 'value:', typeof form.get(key));
          // 如果是多文件上传控件则删除键值
          if (fo(key).type == 'file' && fo(key).getAttribute('multiple') != null) {
            form.delete(key);
            let dropFieldName = key;
            // 可视化上传文件宏控件中可能含有拖放的图片
            let dpFiles = getDropFiles(dropFieldName);
            console.log('getFormData dpFiles', dpFiles);
            if (dpFiles && dpFiles.length > 0) {
              for (let i = 0; i < dpFiles.length; i++) {
                form.append(dropFieldName, dpFiles[i].file);
              }
            }
          } else if (key.indexOf('cws_textarea_') == 0) {
            // console.log('cws_textarea key', key);
            arr[k] = key;
            k++;
          } else if (key.indexOf('nest_field_') == 0 && key.indexOf('nest_field_dataId') == -1) {
            arrNest[j] = key;
            j++;
          }

          // console.log('$(fo(' + key + ")).is(':hidden')", $(fo(key)).is(':hidden'));
          // if ($(fo(key)).is(':hidden') && $(fo(key)).attr('name').indexOf('cws_textarea_') == -1) {
          //   if (cwsHiddenFields == '') cwsHiddenFields = key;
          //   else cwsHiddenFields += ',' + key;
          // }

          // 如果嵌套表对应的表格是隐藏状态
          let element = fo(key);
          // att1 为formData.append的，所以element为null
          if (element == null) continue;

          let name = element.getAttribute('name');
          if ($(element).attr('macroType') == 'nest_sheet') {
            if ($(fo('cwsNestTable_' + $(element).attr('name'))).is(':hidden')) {
              console.log('element hidden nest_sheet', element);
              if (cwsHiddenFields == '') cwsHiddenFields = name;
              else cwsHiddenFields += ',' + name;
            }
          } else if ($(element).attr('macroType') == 'nest_table') {
            if ($(fo('nestTable_' + $(element).attr('name'))).is(':hidden')) {
              console.log('element hidden nest_table', element);
              if (cwsHiddenFields == '') cwsHiddenFields = name;
              else cwsHiddenFields += ',' + name;
            }
          } else {
            if (
              $(fo(key)).is(':hidden') &&
              $(fo(key)).attr('name').indexOf('cws_textarea_') == -1
            ) {
              let isHidden = true;
              // 手写板控件按钮
              if (fo('btn_' + key)) {
                if (!$(fo('btn_' + key)).is(':hidden')) {
                  isHidden = false;
                }
              } else if (fo('upload_box_' + key)) {
                // 文件（断点续传或obs上传）
                if (!$(fo('upload_box_' + key)).is(':hidden')) {
                  isHidden = false;
                }
              }

              if (isHidden) {
                if (cwsHiddenFields == '') cwsHiddenFields = key;
                else cwsHiddenFields += ',' + key;
              }
            }
          }
        }

        // 补充在隐藏元素中加入未选值的radio及checkbox（未选值的不会出现在formData中）
        let frm = o(getFormName.value);
        // console.log('frm.elements', frm.elements);
        for (let i = 0; i < frm.elements.length; i++) {
          let element = frm.elements[i];
          let name = element.getAttribute('name');
          if (
            element.tagName == 'INPUT' &&
            (element.getAttribute('type') == 'radio' || element.getAttribute('type') == 'checkbox')
          ) {
            if ($(element).is(':hidden') && !$(element).is(':checked')) {
              console.log('element hidden readio or checkbox', element);
              if (cwsHiddenFields == '') cwsHiddenFields = name;
              else cwsHiddenFields += ',' + name;
            }
          }
        }

        // 被隐藏元素
        form.append('cwsHiddenFields', cwsHiddenFields);
        form.append('deptOfUserWithMultiDept', selectDeptCode.value);

        // 从form中删除 cws_textarea 元素
        for (let i in arr) {
          form.delete(arr[i]);
        }

        // 从form中删除 nest_field 元素
        // for (let n in arrNest) {
        //   form.delete(arrNest[n]);
        // }

        // // 添加nest_field元素，同时在name在加入nestFieldName
        // $(o(getFormName.value))
        //   .find('div[id^="nestsheet_"][nesttype="nest_table"]')
        //   .each(function () {
        //     let id = this.getAttribute('id');
        //     let nestFieldName = id.substring('nestsheet_'.length);
        //     console.log('nestsheet nestFieldName', nestFieldName);
        //     $(this)
        //       .find('[name^=nest_field_]')
        //       .each(function () {
        //         let name = this.getAttribute('name');
        //         if (name.indexOf('nest_field_dataId') == -1) {
        //           name = name?.substring('nest_field_'.length);
        //           form.append('nest_field_' + nestFieldName + '_' + name, $(this).val());
        //         }
        //       });
        //   });

        try {
          // 取可视化上传控件的图片顺序
          form.append('uploaderImgOrders', getUploaderImgOrders(formRowData.value.formCode));
        } catch (e) {}

        // 加入流程等级、标题等
        for (let v in formRowData.value) {
          form.append(`${v}`, unref(formRowData)[v]);
        }
        let XorNextActionInternalNames = ref<any>([]);

        console.log('matcBranchAndUsertoActions', matcBranchAndUsertoActions);
        console.log('toActions', toActions.value);

        let count = 0;
        let toActionsLen = 0;
        // 加入流程中选定的人员、分支
        if (matcBranchAndUsertoActions.length > 0) {
          toActionsLen = matcBranchAndUsertoActions.length;
          for (let index in matcBranchAndUsertoActions) {
            let item = matcBranchAndUsertoActions[index] as any;
            if (item.xorChecked) {
              XorNextActionInternalNames.value.push(item.internalName);
            }
            for (let checkerIndex in item.checkers) {
              let checker = item.checkers[checkerIndex];
              if (checker.checked) {
                form.append('WorkflowAction_' + item.id, checker.value);
                count++;
              }
            }
          }
        } else {
          toActionsLen = toActions.value.length;
          for (let index in toActions.value) {
            let item = toActions.value[index];
            if (item.xorChecked) {
              XorNextActionInternalNames.value.push(item.internalName);
            }
            for (let checkerIndex in item.checkers) {
              let checker = item.checkers[checkerIndex];
              if (checker.checked) {
                form.append('WorkflowAction_' + item.id, checker.value);
                count++;
              }
            }
          }
        }

        if (formRowData.value.branchMode == 2 && count != toActionsLen) {
          createMessage.warn('全部分支线均需选择用户');
          return null;
        }

        console.log('form', form);

        // xorChecked
        form.append('XorNextActionInternalNames', unref(XorNextActionInternalNames).join(','));

        // 如果启用了obs上传，则此处不需要再加入上传按钮所选的文件
        if (!isObjStoreEnabled.value && !isUseBreakpointResume.value) {
          if (fileList.value.length > 0) {
            fileList.value.forEach((file: UploadProps['fileList'][number], index) => {
              form.append(`att${index + 1}`, file as any);
            });
          }
        }

        if (matchJson.value.isDelayed) {
          form.append('isDelayed', '1');
          form.append('timeDelayedValue', matchJson.value.timeDelayedValue);
          form.append('timeDelayedUnit', matchJson.value.timeDelayedUnit);
        }

        return form;
      }
      // -----------------------------------------------------表单提交结束-------------------------------------------------------------

      // -----------------------------------------------------退回开始-------------------------------------------------------------
      // 退回
      function returnFlow() {
        returnFlowConfirm();
      }

      // 删除流程
      async function delFlow() {
        await getDelFlow({
          flowId: unref(formRowData).flowId,
        }).then(async (res) => {
          if (res.data.res === 0) {
            createMessage.success(res.data.msg);

            // 置刷新标志
            multipleTabStore.updateIsRefreshProcessPage(true);

            handleClose();
          } else {
            createMessage.error(res.data.msg);
          }
        });
      }

      // 放弃流程
      async function discardFlow() {
        await getDiscardFlow({
          flowId: unref(formRowData).flowId,
        }).then(async (res) => {
          if (res.data.res === 0) {
            createMessage.success(res.data.msg);

            // 置刷新标志
            multipleTabStore.updateIsRefreshProcessPage(true);

            handleClose();
          } else {
            createMessage.error(res.data.msg);
          }
        });
      }

      async function readedFlow() {
        // await getReadedFlow({
        //   myActionId: flowProcessData.myActionId,
        // }).then(async (res) => {
        //   if (res.data.res === 0) {
        //     createMessage.success(res.msg);

        //     // 置刷新标志
        //     multipleTabStore.updateIsRefreshProcessPage(true);

        //     handleClose();
        //   } else {
        //     createMessage.error(res.data.msg);
        //   }
        // });

        fo('op').value = 'finish';
        isSpinning.value = true;
        const form = getFormData();
        await getReadedFlow(form).then(async (res) => {
          isSpinning.value = false;

          if (res.data.res == -1) {
            createMessage.error(res.data.msg);
            return;
          }

          createMessage.success(res.msg);

          // 置刷新标志
          multipleTabStore.updateIsRefreshProcessPage(true);

          handleClose();
        });
      }

      // 拒绝流程
      async function disagreeFlow() {
        let isFlowReturnWithRemark = flowProcessData.isFlowReturnWithRemark;
        if (isFlowReturnWithRemark) {
          if (!formRowData.value.cwsWorkflowResult) {
            createMessage.warning(t('flow.leavewordPlaceholder'));
            o(`cwsWorkflowResult_${getFormName.value}`).focus();
            $(o(`cwsWorkflowResult_${getFormName.value}`)).addClass('LV_invalid_field');
            return;
          }
        }

        fo('op').value = 'manualFinish';
        isSpinning.value = true;
        const form = getFormData();
        await getFinishAction(form).then(async (res) => {
          isSpinning.value = false;
          createMessage.success(res.msg);

          // 置刷新标志
          multipleTabStore.updateIsRefreshProcessPage(true);

          handleClose();
        });
      }

      // 同意并结束流程
      async function finishAgreeFlow() {
        fo('op').value = 'manualFinishAgree';
        isSpinning.value = true;
        const form = getFormData();
        await getFinishAction(form).then(async (res) => {
          isSpinning.value = false;
          createMessage.success(res.msg);

          // 置刷新标志
          multipleTabStore.updateIsRefreshProcessPage(true);

          handleClose();
        });
      }

      function handleCwsWorkflowResultChange() {
        if (formRowData.value.cwsWorkflowResult) {
          $(o(`cwsWorkflowResult_${getFormName.value}`)).removeClass('LV_invalid_field');
        }
      }

      // 退回需选择的用户或节点数据
      const returnFlowVisible = ref(false);
      // 是否正退回
      const isReturning = ref(false);
      const importVisible = ref(false);
      const returnResult = ref<any>([]);
      const aryReturnAction = ref<any>([]);
      const returnIdValueRadio = ref('');
      let isReturnStyleFree = ref(false);
      async function returnFlowConfirm() {
        let isFlowReturnWithRemark = flowProcessData.isFlowReturnWithRemark;
        if (isFlowReturnWithRemark) {
          if (!formRowData.value.cwsWorkflowResult) {
            createMessage.warning(t('flow.leavewordPlaceholder'));
            o(`cwsWorkflowResult_${getFormName.value}`).focus();
            $(o(`cwsWorkflowResult_${getFormName.value}`)).addClass('LV_invalid_field');
            return;
          }
        }

        // 退回时不能用LiveValidation校验必填，因为可能有的必填项是提交时必填，而非退回时必填
        // 退回时验证数据合法性
        if (typeof checkOnReturnBack == 'function') {
          try {
            // 在form_js_formCode.js中写此方法
            var r = checkOnReturnBack(getFormName.value);
            if (r != '') {
              createMessage.warning(r);
              return;
            }
          } catch (e) {
            console.error(e);
          }
        }

        isReturnStyleFree.value = flowProcessData.isReturnStyleFree;
        if (isReturnStyleFree.value) {
          isSpinning.value = true;
          await getReturnAction({
            actionId: unref(formRowData).actionId,
            flowId: unref(formRowData).flowId,
          })
            .then(async (data) => {
              returnResult.value = data.result || [];

              if (returnResult.value.length === 1) {
                returnIdValueRadio.value = returnResult.value[0].returnId;
              } else {
                returnIdValueRadio.value = '';
              }
            })
            .finally(() => {
              isSpinning.value = false;
            });
        } else {
          aryReturnAction.value = flowProcessData.aryReturnAction || [];
          if (aryReturnAction.value.length === 1) {
            returnIdValueRadio.value = aryReturnAction.value[0].actionId;
          } else {
            returnIdValueRadio.value = '';
          }
          aryReturnAction.value.forEach((item: any) => {
            item.label = item.actionTitle + '  ' + item.realName;
            item.value = item.actionId;
          });
        }
        returnFlowVisible.value = true;
      }

      //返回最终确认 Modal
      async function handleReturnFlow(e, isAfterOnlyofficeSave = false) {
        fo('op').value = 'return';
        if (!returnIdValueRadio.value) {
          createMessage.warning('请选择需返回的用户');
          return;
        }

        isSpinning.value = true;
        let formData = getFormData();
        formData.append('returnId', returnIdValueRadio.value);

        // onlyoffice保存文件
        if (typeof handleOnlyofficeSave == 'function') {
          if (!isAfterOnlyofficeSave) {
            returnFlowVisible.value = false;
            isReturning.value = false;
            handleOnlyofficeSave(getFormName.value, 2);
            return;
          }
        }

        isReturning.value = true;
        await getFinishAction(formData)
          .then((res) => {
            createMessage.success(res.msg);
            showResponse(res);
          })
          .catch((e) => createMessage.warning(e.msg))
          .finally(() => {
            isReturning.value = false;
            returnFlowVisible.value = false;
            isSpinning.value = false;
          });
      }
      // -----------------------------------------------------退回结束-------------------------------------------------------------

      // -----------------------------------------------------文件上传开始-------------------------------------------------------------
      //上传前校验
      const beforeUpload: UploadProps['beforeUpload'] = (file) => {
        fileList.value = [...fileList.value, file];
        return false;
      };
      // 上传文件删除
      const handleRemove: UploadProps['onRemove'] = (file) => {
        const index = fileList.value.indexOf(file);
        const newFileList = fileList.value.slice();
        newFileList.splice(index, 1);
        fileList.value = newFileList;
      };

      // -----------------------------------------------------文件上传结束-------------------------------------------------------------
      // -----------------------------------------------------文件列表开始-------------------------------------------------------------
      const columns: BasicColumn[] = [
        {
          title: '标题',
          dataIndex: 'name',
          align: 'left',
          width: '350px',
          slots: { customRender: 'attTitle' },
        },
        {
          title: '创建者',
          dataIndex: 'creatorRealName',
        },
        {
          title: '创建时间',
          dataIndex: 'createDate',
          customRender: ({ text }) => {
            return dayjs(text).format('YYYY-MM-DD HH:mm:ss');
          },
        },
        {
          title: '大小',
          dataIndex: 'fileSizeMb',
        },
      ];
      let attachments = ref([]);
      const [registerTable, { reload: reloadAttachment, setProps }] = useTable({
        title: '', // '附件列表',
        api: getListAttachment,
        columns,
        formConfig: {},
        searchInfo: {}, //额外的参数
        useSearchForm: false,
        showTableSetting: false,
        bordered: true,
        indexColumnProps: { width: 50 },
        showIndexColumn: true,
        immediate: false,
        pagination: false,
        canResize: false,
        afterFetch: (data) => {
          if (data && data.length > 0) {
            aryAttSize.value = data.length;
            attachments.value = data;
          }
        },
        actionColumn: {
          width: 180,
          title: '操作',
          dataIndex: 'action',
          slots: { customRender: 'action' },
          fixed: undefined,
        },
      });
      //文件列表删除
      function handleDelete(record) {
        console.log('handleDelete record', record);
        let params = {
          flowId: unref(formRowData).flowId,
          attId: record.id,
        };
        getListAttachmentDelAtt(params).then(() => {
          if (record.fieldName && record.fieldName.length > 0) {
            handleRefresh();
          } else {
            reloadAttachment();
          }
        });
      }

      function handleDownload(record: any) {
        if (serverInfo.isObjStoreEnabled) {
          getObjectByKey(record.visualPath + '/' + record.diskName, record.name);
        } else {
          record.isDownloadAtt = true;
          const params = {
            flowId: formRowData.value.flowId,
            attachId: record.id,
          };
          getDownload(params)
            .then((data) => {
              if (data) {
                downloadByData(data, `${record.name}`);
              }
            })
            .finally(() => {
              record.isDownloadAtt = false;
            });
        }
      }

      function handleDownloadOfd(record: any) {
        record.isDownloadAttOfd = true;
        const params = {
          flowId: formRowData.value.flowId,
          attachId: record.id,
        };
        getDownloadOfd(params)
          .then((data) => {
            if (data) {
              const lastIndex = record.name.lastIndexOf('.');
              downloadByData(data, `${record.name.substring(0, lastIndex) + '.ofd'}`);
            }
          })
          .finally(() => {
            record.isDownloadAttOfd = false;
          });
      }

      // -----------------------------------------------------文件列表结束-------------------------------------------------------------
      const onClickMenu: MenuProps['onClick'] = ({ key }) => {
        console.log(`Click on item ${key}`);
        if (key === 'form') {
          htmlPrint('flowForm');
        } else if (key === 'all') {
          htmlPrint('flowFormBox');
        } else {
          openProcessViewDrawerForPrint(unref(formRowData).flowId, key);
        }
      };
      function htmlPrint(ele: string) {
        // 去掉加载失败的图片，因其会导致无法打印
        $(fo(ele))
          .find('img')
          .each(function () {
            console.log('htmlPrint', this);
            if (this.getAttribute('loaded') && this.getAttribute('loaded') != 'true') {
              console.log('htmlPrint remove', this);
              $(this).remove();
            }
          });
        printJS({
          printable: document.getElementById(ele),
          type: 'html',
          targetStyles: ['*'], // 继承原来的所有样式
          css: '/resource/css/print-js.css',
          scanStyles: false, // css库将不处理应用于正在打印的html的样式，与css参数联用
          // ignoreElements: ['no-print', 'bc', 'gb'],
          // maxWidth: 800,
          style:
            '@page {margin:10 0mm} .tabStyle_8 {width: 96% !important; .table-lte {width: 96% !important;}',
        });
      }
      // -----------------------------------------------------关联模块处理抽屉开始-------------------------------------------------------------

      const [registerSmartModuleRelateTableDrawer, { openDrawer: openSmartModuleRelateDrawer }] =
        useDrawer();

      let moduleCodeRelated = '',
        nestFieldName = '';
      function openSmartModuleRelateTableDrawer(type = 1, params: Recordable) {
        console.log('openSmartModuleRelateTableDrawer params', params);
        nestFieldName = params.nestFieldName;
        if (type == 1) {
          /* // 注意添加时用的是relate抽屉，而编辑时不是
          openSmartModuleRelateDrawer(true, {
            isUpdate: type, // 1 新增，2 编辑，3 详情
            record: {
              ...params,
              actionId: unref(formRowData).actionId,
              // moduleCode: '',
              // moduleCodeRelated: '',
              // parentId: '',
            },
          }); */
          console.log('openSmartModuleRelateTableDrawer params', params);
          moduleCodeRelated = params.moduleCodeRelated;
          openSmartModuleDrawer(true, {
            isUpdate: type, // 1 新增，2 编辑，3 详情
            record: {
              ...params,
              actionId: unref(formRowData).actionId,
            },
          });
        } else {
          moduleCodeRelated = params.moduleCodeRelated;
          openSmartModuleDrawer(true, {
            isUpdate: type,
            record: {
              moduleCode: params.moduleCodeRelated,
              id: params.id,
              flowId: unref(formRowData).flowId,
              actionId: unref(formRowData).actionId,
              pageType: params.pageType,
              nestFieldName: nestFieldName,
            },
          });
        }
      }

      function smartModuleRelateTableDrawerhandleSuccess({ moduleCodeRelated, nestFieldName }) {
        // 刷新嵌套表
        eval(
          'reloadNestSheetCtl("' +
            moduleCodeRelated +
            '", "' +
            nestFieldName +
            '", "' +
            getFormName.value +
            '")',
        );
      }

      // -----------------------------------------------------关联模块处理抽屉结束-------------------------------------------------------------

      // -----------------------------------------------------选择模块开始-------------------------------------------------------------

      const [registerSmartModuleSelDrawer, { openDrawer: openSmartModuleSelDrawer }] = useDrawer();

      let myStart = 1;
      function openSmartModuleSelTableDrawer(selMode = 1, start = 1, params: object) {
        console.log('process openModuleSelDrawer');
        myStart = start;
        openSmartModuleSelDrawer(true, {
          selMode, // 1 单选，2 多选
          start, // 1 表单域选择 2 嵌套表格拉单
          record: {
            ...params,
          },
        });
      }

      // 处理表单域选择窗口关闭事件
      function handleSmartModuleSelCallBack(rows) {
        // if (rows.size() > 1) {
        //    createMessage.warning('请选择一条记录');
        // }
        console.log('流程的抽屉', rows, 'myStart', myStart);
        let params: any = getCurModuleFieldListParams();
        console.log('params', params);
        if (myStart == 1) {
          params.id = rows[0].ID;
          params.cwsFormName = getFormName.value;
          let thisBody: Object = document.body;
          // 给表单域控件赋值，并带入其映射字段
          getItemsForListModuleSel(params).then(async (res) => {
            // console.log(res.data);
            $(thisBody).append(res.data);

            // 不能再filterJS，会造成重复，因为jQuery append会执行其中的js
            // isSpinning.value = true;
            // await filterJS(res.data, 'items', getFormName.value);
            // isSpinning.value = false;

            $('.helper-module-list-sel').remove();
            removeScript('items');
            console.log('handleSmartModuleSelCallBack params', params);
            try {
              onModuleSelForField(params);
            } catch (e) {}
          });
        } else if (myStart == 2) {
          let ids = '';
          for (let k in rows) {
            if (ids == '') {
              ids = rows[k].ID;
            } else {
              ids += ',' + rows[k].ID;
            }
          }
          params.ids = ids;
          params.flowId = unref(formRowData).flowId;
          getSelBatchForNest(params).then(async (res) => {
            console.log('handleSmartModuleSelCallBack res', res);
            if (res.code == 500) {
              createMessage.error(res.msg);
              return;
            }

            await filterJS(res.data.script, 'items', getFormName.value);
            // 刷新嵌套表
            if (params.nestType == 'nest_sheet') {
              eval(
                'reloadNestSheetCtl("' +
                  params.moduleCode +
                  '","' +
                  params.nestFieldName +
                  '", "' +
                  getFormName.value +
                  '")',
              );
            } else {
              eval('refreshNestTableCtl' + params.nestFieldName + '()');
            }

            removeScript('items');

            console.log('params', params);
            try {
              onModuleSelForNest(params);
            } catch (e) {}
          });
        } else if (myStart == 3) {
          let ids = '';
          for (let k in rows) {
            if (ids == '') {
              ids = rows[k].ID;
            } else {
              ids += ',' + rows[k].ID;
            }
          }

          try {
            handleModuleListSel(ids);
          } catch (e) {
            console.warn('form_js 中未设置 handleModuleListSel, ids:' + ids);
            console.log(e);
          }
        }
      }

      function clearSmartModuleSel() {
        setInputObjValue('', '');
      }
      // -----------------------------------------------------选择模块结束-------------------------------------------------------------

      // ----------------------------------------------------嵌套表中查看开始-------------------------------------
      const [registerSmartModuleDrawer, { openDrawer: openSmartModuleDrawer }] = useDrawer();
      function openSmartModuleDrawerForShow(moduleCode, id, visitKey, params) {
        console.log('openSmartModuleDrawerForShow params', params, 'isTab', isTab.value);
        if (unref(isTab)) {
          go({
            path: '/smartModuleAddEditView',
            query: {
              isTab: true,
              isUpdate: 3,
              parentPath: unref(currentRoute).path,
              moduleCode: moduleCode,
              id: id,
              visitKey: visitKey,
              titleName: `详情`,
              cacheName: `smartModuleAddEditViewDetail${id}`,
              ...params,
            },
          });
        } else {
          openSmartModuleDrawer(true, {
            isUpdate: 3,
            record: {
              moduleCode,
              id,
              visitKey,
              ...params,
            },
          });
        }
      }

      function openSmartModuleDrawerForEdit(moduleCode, id, visitKey) {
        let params = {
          moduleCode,
          id,
          visitKey,
        };
        openSmartModuleDrawer(true, {
          isUpdate: 2,
          record: {
            ...params,
          },
        });
      }

      function handleSmartModuleCallBack(data) {
        // 刷新嵌套表
        try {
          eval(
            'reloadNestSheetCtl("' +
              moduleCodeRelated +
              '", "' +
              nestFieldName +
              '", "' +
              getFormName.value +
              '", "' +
              data.id +
              '")',
          );
        } catch (e) {
          console.warn(e);
        }
      }
      // ----------------------------------------------------嵌套表中查看开始结束-------------------------------------

      // ----------------------------------------------------嵌套表中流程查看开始-------------------------------------
      const [registerProcessShowDrawer, { openDrawer: openProcessShowDrawer }] = useDrawer();
      function openProcessShowDrawerForShow(flowId, visitKey) {
        let params = {
          flowId,
          visitKey,
          isTab: false,
        };
        openProcessShowDrawer(true, params);
      }

      function handleProcessShowCallBack(rows) {
        initWindowFunc();
      }
      // ----------------------------------------------------嵌套表中流程查看结束-------------------------------------

      // ----------------------------------------------------我的流程宏控件选择流程开始-------------------------------------
      const [registerProcessSelectDrawer, { openDrawer: openProcessSelDrawer }] = useDrawer();
      function openProcessSelectDrawer() {
        let params = {};
        openProcessSelDrawer(true, params);
      }

      function handleProcessSelect(params) {
        console.log('handleProcessSelect params', params);
        setInputObjValue(params.flowId, params.title);
      }
      // ----------------------------------------------------我的流程宏控件选择流程结束-------------------------------------

      // ----------------------------------------------------视图查看开始-------------------------------------
      const [registerProcessViewDrawer, { openDrawer: openProcessViewDrawer }] = useDrawer();
      function openProcessViewDrawerForPrint(flowId, viewId) {
        let params = {
          flowId,
          viewId,
        };
        openProcessViewDrawer(true, params);
      }

      function handleProcessViewCallBack() {}
      // ----------------------------------------------------视图查看结束-------------------------------------

      // -----------------------------------------------------查看流程图开始-------------------------------------------------------------

      const [registerFlowChartDrawer, { openDrawer: openFlowChartDrawer }] = useDrawer();

      function openFlowChartInfoDrawer() {
        openFlowChartDrawer(true, {
          flowId: unref(formRowData).flowId,
        });
      }
      // -----------------------------------------------------查看流程图结束-------------------------------------------------------------
      // -----------------------------------------------------管理开始-------------------------------------------------------------
      function handleManager() {
        // go({
        //   path: '/flowManagement',
        //   query: {
        //     typeCode: flowProcessData.flowTypeCode,
        //   },
        // });

        let routeUrl: any = {};
        routeUrl = resolve({
          path: '/designViewPage',
          query: {
            type: 'flow',
            typeCode: flowProcessData.flowTypeCode,
            formCode: formRowData.value.formCode,
            pageName: currentRoute.value.meta.title,
            name: formRowData.value.cwsWorkflowTitle,
            token: getToken() as any,
          },
        });
        const height = screen.height;
        const width = screen.width;
        console.log({
          routeUrl,
          height,
          width,
        });
        window.open(
          routeUrl.href,
          '',
          `height=${height},width=${width},top=0, left=0,alwaysRaised=true,toolbar=no,location=no,resizable=no, scrollbars=yes ,`,
        );
      }
      // -----------------------------------------------------管理结束-------------------------------------------------------------

      function handlePrintBtnClick(viewId) {
        console.log('btn params', viewId);
      }

      // -----------------------------------------------------debug开始-------------------------------------------------------------

      const [registerDebugDrawer, { openDrawer: openDebugDrawer }] = useDrawer();
      function handleDebug() {
        openDebugDrawer(true, {
          isUpdate: false,
          myActionId: formRowData.value.myActionId,
        });
      }

      async function handleRefresh() {
        // 如果不清除content，就会使得不可写字段及可视化上传控件的值被刷新后因脚本再次赋值出现有重复
        // 可能getFlowProcessContent取得的content与之前的一样，所以vue就不去清除content再重新赋予值了
        // 也就是说原来的内容还在，并未被清除
        content.value = '';
        // 删除原来的js脚本，以免重复运行
        removeScript('-src');
        await getFlowProcessContent(unref(formRowData).myActionId);
      }

      // -----------------------------------------------------debug结束-------------------------------------------------------------

      // ---------------------------------------------------------------------------嵌套表导出导入开始-----------------------------------------------------------
      //导出
      async function exportExcelRelate(
        nestType,
        parentId,
        formCode,
        formCodeRelated,
        title = '导出',
      ) {
        let params = {
          nestType,
          parentId,
          moduleCode: formCode,
          moduleCodeRelated: formCodeRelated,
        };
        isSpinning.value = true;
        getVisualExportExcelRelate(params)
          .then((data) => {
            if (data) {
              console.log('exportExcelRelate 导出 ' + title);
              downloadByData(data, `${title}.xls`);
            } else {
              console.error('exportExcelRelate 导出失败');
            }
          })
          .finally(() => {
            isSpinning.value = false;
          });
      }

      let excelParams: any = {};
      function openImportExcelModal(
        parentId,
        moduleCode,
        parentFormCode,
        flowId,
        nestFieldName,
        nestType = 'nest_sheet',
      ) {
        importVisible.value = true;
        excelParams = {
          parentId,
          moduleCode,
          parentFormCode,
          flowId,
          nestFieldName,
          nestType,
        };
      }

      //获取files
      function rawFileFn(files) {
        let formData = new FormData();
        formData.append('att1', files);
        formData.append('parentId', excelParams.parentId);
        formData.append('moduleCode', excelParams.moduleCode);
        formData.append('parentFormCode', excelParams.parentFormCode);
        formData.append('flowId', excelParams.flowId);
        let query = '?parentId=' + excelParams.parentId;
        isImport.value = true;
        getVisualImportExcelNest(formData, query)
          .then(() => {
            createMessage.success('操作成功');
            if (excelParams.nestType == 'nest_sheet') {
              // 刷新嵌套表
              eval(
                'reloadNestSheetCtl("' +
                  excelParams.moduleCode +
                  '","' +
                  excelParams.nestFieldName +
                  '", "' +
                  getFormName.value +
                  '")',
              );
            } else {
              eval('refreshNestTableCtl' + excelParams.nestFieldName + '()');
            }
          })
          .finally(() => {
            isImport.value = false;
            importVisible.value = false;
          });
      }

      function handleDownloadExcelTempl() {
        isDownload.value = true;
        getVisualDownloadExcelTemplForNest(excelParams).then((data) => {
          isDownload.value = false;
          let title = '模板';
          if (data) {
            downloadByData(data, `${title}.xls`);
          }
        });
      }

      // ---------------------------------------------------------------------------嵌套表导出导入结束-----------------------------------------------------------

      //初始化
      watch(
        () => props.myActionId,
        async (newVal, oldVal) => {
          console.log('newVal', newVal, 'oldVal', oldVal);
          if (newVal !== oldVal) {
            isSpinning.value = false;
            if (!isDoLoading.value && !!props.myActionId) {
              removeScript(srcId.value);
              setTimeout(() => {
                getFlowProcessContent(props.myActionId);
              }, 100);
            }
          }
        },
        {
          // 0611 如果为true，可能会调两次getFlowProcessContent，在上面加上了判断 newVal !== oldVal也没用
          // immediate: true,
        },
      );
      //发起流程
      const beginLaunch = (typeCode: string) => {
        return new Promise((resolve) => {
          isSpinning.value = true;
          getFlowInit({ typeCode: typeCode })
            .then((res) => {
              isLaunched.value = true;
              let myActionId = res.myActionId || '';
              if (myActionId) {
                getFlowProcessContent(myActionId);
              }
            })
            .finally(() => {
              resolve(true);
              //isSpinning.value = false;
            });
        });
      };
      const query = ref<any>({});
      const typeCode = ref<any>(null);
      const isTab = ref(false); // 是否在新选项卡中打开，当在launch.vue中打开时，isTab为true
      let isFirst = false; // 是否第一次进入

      onMounted(async () => {
        isFirst = true;

        removeScript(srcId.value);
        console.log('route', route);
        // debug模式入口或从发起流程页面launch.vue进入
        if (route.query) {
          query.value = route.query;
          isTab.value = query.value.isTab ? query.value.isTab : false;
        }
        // 从菜单进入，但进入的不是门户
        if (route.meta.formCode && route.meta.preCode != 'portals') {
          // 如果不是智能模块列表页，则置isTab为true，如果是列表页，则应是点击了列表页的发起流程按钮
          if (route.meta.preCode != 'module') isTab.value = true;
        }
        // 从processShowView进入
        if (query.value.isFromShowView || query.value.isFromProcess) {
          isTab.value = true;
          if (route.query.title) {
            setTitle(route.query.title);
          }
        }
        // 从待办列表进入或来自于processShowView中的处理按钮
        if (query.value.myActionId) {
          await getFlowProcessContent(query.value.myActionId);
        }
        if (query.value.isDebug == 'true') {
          userStore.setIsDebug(query.value.isDebug);
        }

        //流程模块入口
        console.log('onmounted route', route);
        console.log('props.myActionId', props.myActionId);
        // 从操作列发起流程时，route.meta.formCode中也可能是有值的，但是此时myActionId已经有了，故可以根据此来判断是否beginLaunch
        if (!props.myActionId || props.myActionId === 0) {
          // 当在模块列表页时，route.meta.formCode的值为当前的模块编码，当在模块列表的工具条按钮中发起流程时，需通过type来判断
          // 当菜单类型为发起流程时
          if (route.meta.formCode && route.meta.type === 3) {
            typeCode.value = route.meta?.formCode;
            // console.log('typeCode', typeCode.value);
            beginLaunch(typeCode.value);
          }
        } else {
          // 防止出现先发起自由流程，关闭抽屉，再发起固定流程，watch无效的问题
          if (!isDoLoading.value) {
            removeScript(srcId.value);
            setTimeout(() => {
              getFlowProcessContent(props.myActionId);
            }, 100);
          }
        }
      });

      let isCached = true;

      onActivated(() => {
        isCached = true;
        console.log('process onActivated isDoLoading', isDoLoading.value);
        initWindowFunc();
        console.log('onActivated initWindowFunc');

        console.log('onActivated isFirst', isFirst);

        setTimeout(() => {
          // 如果是第一次进入页面，不能调用initContent
          if (!isFirst) {
            // 如果加载未完成，则继续
            // if (isDoLoading.value) {
            //   console.log('process onActivated initContent');
            //   // initContent();
            // }

            // 如果加载未完成，则重新加载
            if (isDoLoading.value || curFormUtil?.isFormLoading(getFormName.value)) {
              if (curFormUtil?.isFormLoading(getFormName.value)) {
                // 复位表单加载标志
                curFormUtil?.resetFormLoading(getFormName.value);
                console.warn(
                  'Form: ' + getFormName.value + "'s loading flag is true, need to be reload.",
                );
              }

              console.log('process onActivated getFlowProcessContent');
              removeScript(srcId.value);
              content.value = '';

              // 从待办列表进入或来自于processShowView中的处理按钮
              if (query.value.myActionId) {
                getFlowProcessContent(query.value.myActionId);
              } else if (!!props.myActionId) {
                getFlowProcessContent(props.myActionId);
              } else {
                if (route.meta.formCode && route.meta.type === 3) {
                  typeCode.value = route.meta?.formCode;
                  console.log('onActivated typeCode', typeCode.value);
                  beginLaunch(typeCode.value);
                }
              }
            }
          }

          // if (multipleTabStore.isRefreshPage) {
          //   console.log('formRowData.value.myActionId', formRowData.value.myActionId);
          //   if (formRowData.value.myActionId && formRowData.value.myActionId != -1) {
          //     // handleRefresh();
          //     isSpinning.value = true;

          //     // 清空数据
          //     content.value = '';
          //     setTableData([]);

          //     typeCode.value = route.meta?.formCode;
          //     // console.log('typeCode', typeCode.value);
          //     beginLaunch(typeCode.value);
          //   }
          //   multipleTabStore.updateIsRefreshPage(false);
          // }
          try {
            // 用于form_js中的定时器检测是否可继续执行
            eval('onActivated_' + formRowData.value.formCode + '(1, typeCode.value)');
          } catch (e) {
            // console.error(e);
            console.warn('form_js_' + formRowData.value.formCode + ' 中无onActivated方法');
          }

          isFirst = false;
        }, 100);
      });

      onDeactivated(() => {
        isCached = false;
        console.log('processHandle onDeactivated');

        if (isDoLoading.value) {
          createMessage.warn('请等待流程加载完成后，再切换页面');
        }

        try {
          // 用于form_js中的定时器检测是否可继续执行
          eval('onDeactivated_' + formRowData.value.formCode + '(1, typeCode.value)');
        } catch (e) {
          // console.error(e);
          console.warn('form_js_' + formRowData.value.formCode + ' 中无onDeactivated方法');
        }
      });

      // 如果菜单项被缓存，则关闭选项卡时会调用到此事件
      onUnmounted(() => {
        console.log('Unmounted in processHandleView!');
        clearFormCtl();
        curFormUtil?.close(getFormName.value);
      });

      function getServerUrl() {
        return userStore.getServerUrl;
      }

      function getPublicPath() {
        const publicPath = import.meta.env.VITE_PUBLIC_PATH || '/';
        return publicPath;
      }

      function getCurFormId() {
        // 注意可能会造成有的页面中忘了设置getCurFormId，导致fo调用getCurFormId时将本页的formName认为是当前form
        // return getFormName.value;
        return curFormUtil?.get();
      }

      function getCurFormUtil() {
        return curFormUtil;
      }

      function showSpinning(isShow) {
        isSpinning.value = isShow;
      }

      const getFormName = computed(() => 'flowForm' + curFormUtil?.getFormNo());

      function initWindowFunc() {
        console.log('initWindowFunc getFormName.value=' + getFormName.value);
        // initWindowFunc中需延时置curFormUtil.set(...)，否则当切换选项卡时，如从列表页切至流程处理页，列表页onunmounted可能会滞后，导致其中curFormUtil.close()处理的是本页面的formId
        setTimeout(() => {
          curFormUtil?.set(getFormName.value);
        }, 100);

        let newWindow = window as any;
        newWindow.onRendEnd = onRendEnd;
        newWindow.getCurFormId = getCurFormId;
        newWindow.getCurFormUtil = getCurFormUtil;
        newWindow.ajaxPost = ajaxPost;
        newWindow.ajaxGet = ajaxGet;
        newWindow.ajaxGetJS = ajaxGetJS;
        newWindow.filterJS = filterJS;
        newWindow.selectUserInForm = selectUserInForm;
        newWindow.openSmartModuleRelateTableDrawer = openSmartModuleRelateTableDrawer;
        newWindow.myConfirm = myConfirm;
        newWindow.myMsg = myMsg;
        newWindow.openSmartModuleSelTableDrawer = openSmartModuleSelTableDrawer;
        newWindow.submitMyFile = submitMyFile;
        // 表单域选择宏控件在查看时会用到
        newWindow.openSmartModuleDrawerForShow = openSmartModuleDrawerForShow;
        newWindow.openProcessShowDrawerForShow = openProcessShowDrawerForShow;
        newWindow.exportExcelRelate = exportExcelRelate;
        newWindow.openSmartModuleDrawerForEdit = openSmartModuleDrawerForEdit;
        newWindow.openImportExcelModal = openImportExcelModal;
        newWindow.getToken = getToken;
        newWindow.getServerUrl = getServerUrl;
        newWindow.ajaxPostJson = ajaxPostJson;
        newWindow.downloadFile = downloadFile;
        newWindow.reloadAttachment = reloadAttachment;
        newWindow.getPublicPath = getPublicPath;
        newWindow.openInputPwdModal = openInputPwdModal;
        newWindow.openSelStampModal = openSelStampModal;
        newWindow.showImage = showImage;
        newWindow.openWritePadModal = openWritePadModal;
        newWindow.removePhrase = removePhrase;
        newWindow.openSelDeptModal = openSelDeptModal;
        newWindow.openLocationMarkModal = openLocationMarkModal;
        newWindow.initFormCtl = initFormCtl;
        newWindow.showSpinning = showSpinning;
        newWindow.downloadFileVisual = downloadFileVisual; // 映射的文件宏控件下载

        newWindow.selectFiles = handleSelectFiles;
        newWindow.getServerInfo = getServerInfo;
        newWindow.deleteByField = deleteByField;
        newWindow.downloadObsFile = handleDownloadObsFile;
        newWindow.setUploadFileTreeListAttInfo = setUploadFileTreeListAttInfo;
        newWindow.openLocationMarkTdModal = openLocationMarkTdModal;
        newWindow.openScriptDesigner = openScriptDesigner;

        newWindow.loadImgInJar = loadImgInJar;
        newWindow.generateTab = generateTab;
        newWindow.handleBtnClick = handleBtnClick;

        newWindow.doPause = doPause;
        newWindow.doStart = doStart;
        newWindow.doCancel = doCancel;
        newWindow.openProcessSelectDrawer = openProcessSelectDrawer;
        newWindow.runConnector = runConnector;
        newWindow.goRoute = go;

        newWindow.toolbarSubmit = toolbarSubmit;
        newWindow.saveDraft = saveDraft;
        newWindow.handleReturnFlow = handleReturnFlow;
      }

      const [registerModal, { openModal }] = useModal();

      //debug回调
      function handleDeBugCallBack() {
        getFlowProcessContent(formRowData.value.myActionId);
      }

      // -----------------------------------------------------处理过程开始-------------------------------------------------------------
      const handleColumns: BasicColumn[] = [
        {
          title: '办理部门',
          dataIndex: 'depts',
          align: 'center',
          width: '100px',
        },
        {
          title: '处理人',
          dataIndex: 'userRealName',
          align: 'center',
          width: '100px',
          slots: { customRender: 'userRealName' },
        },
        {
          title: '转交人',
          dataIndex: 'privRealName',
          align: 'center',
          width: '100px',
          slots: { customRender: 'privRealName' },
          ifShow: () => formRowData.value.isFlowManager,
        },
        // {
        //   title: '代理人',
        //   dataIndex: 'isProxy',
        //   align: 'center',
        // },
        {
          title: '任务',
          dataIndex: 'actionTitle',
          align: 'center',
          width: '120px',
          ifShow: () => formRowData.value.isFlowManager,
        },
        {
          title: '收到时间',
          dataIndex: 'receiveDate',
          align: 'center',
          width: '100px',
          customRender: ({ text }) => {
            if (text) {
              return dayjs(text).format('MM-DD HH:mm');
            }
          },
        },
        {
          title: '处理时间',
          dataIndex: 'checkDate',
          align: 'center',
          width: '100px',
          customRender: ({ text }) => {
            if (text) {
              return dayjs(text).format('MM-DD HH:mm');
            }
          },
        },
        {
          title: '用时',
          dataIndex: 'workDuration',
          align: 'center',
          width: '90px',
          ifShow: () => formRowData.value.isFlowManager,
        },
        {
          title: '状态',
          dataIndex: 'checkStatusName',
          align: 'center',
          width: '60px',
        },
        {
          title: t('flow.leaveword'),
          dataIndex: 'result',
          align: 'center',
          width: '200px',
          slots: { customRender: 'result' },
          ifShow: () => formRowData.value.isRemarkShowInProcessList,
        },
      ];
      const [registerHandleTable, { setTableData }] = useTable({
        title: '',
        api: '',
        columns: handleColumns,
        formConfig: {},
        searchInfo: {}, //额外的参数
        useSearchForm: false,
        showTableSetting: false,
        bordered: false,
        indexColumnProps: { width: 50 },
        showIndexColumn: true,
        immediate: false,
        pagination: false,
        canResize: false,
        /* actionColumn: {
          width: 80,
          title: '操作',
          dataIndex: 'action',
          slots: { customRender: 'action' },
          fixed: 'right',
        }, */
      });

      //导入modal取消
      function handleCancel() {
        importVisible.value = false;
      }

      // ------------------------------------加签开始----------------------------------------------

      const [registerCountersignModal, { openModal: openCountersignModal }] = useModal();
      //加签modal
      const handleCountersign = () => {
        openCountersignModal(true, {
          isUpdate: true,
          isFlowStarted: formRowData.value.isFlowStarted,
          myActionId: formRowData.value.myActionId,
          record: {},
        });
      };
      //加签modal回调
      const handleCountersignCallBack = (plusType, desc) => {
        formRowData.value.plusDesc = desc;
        isPlusDescShow.value = true;
        console.log('handleCountersignCallBack', plusType, desc);
        // 如果为前加签，则关闭抽屉
        if (plusType == 0) {
          createMessage.success('前加签成功');
          let isDebug = flowProcessData.isDebug;
          if (isDebug) {
            let isDebugCache = getIsDebug();
            if (isDebugCache == 'true') {
              go({
                path: '/flowDebugPage',
                query: {
                  myActionId: flowProcessData.myActionId,
                  flowId: flowProcessData.flowId,
                },
              });
            } else {
              userStore.setIsDebug('false');
              handleClose();
              go({
                path: '/flowDebug',
                query: {
                  myActionId: flowProcessData.myActionId,
                  flowId: flowProcessData.flowId,
                },
              });
            }
          } else {
            handleClose();
          }
        }

        // 置刷新标志
        multipleTabStore.updateIsRefreshProcessPage(true);
      };

      async function delPlus() {
        let params = {
          actionId: formRowData.value.actionId,
        };
        await getDelPlus(params);
        isPlusDescShow.value = false;
        formRowData.value.plusDesc = '';
      }

      // ------------------------------------加签结束----------------------------------------------

      // ------------------------------------抄送开始----------------------------------------------
      const [registerDistributeModal, { openModal: openDistributeModal }] = useModal();
      //展示抄送modal
      const handleDistribute = () => {
        openDistributeModal(true, {
          isUpdate: true,
          record: formRowData,
        });
      };
      //抄送modal回调
      const handleDistributeCallBack = () => {};
      // ------------------------------------抄送结束----------------------------------------------

      const [registerSelTemplateModal, { openModal: openSelTemplateModal }] = useModal();
      const handleSelTemplate = (record) => {
        openSelTemplateModal(true, {
          ...record,
        });
      };

      async function handleSelTemplateCallBack(record) {
        console.log(record);
        record.isDoDocInRed = true;
        convertToRedDocument({
          flowId: formRowData.value.flowId,
          templateId: record.templateId,
          attachId: record.attachId,
        })
          .then((data) => {
            if (data.res == 0) {
              createMessage.success('操作成功');
              reloadAttachment();
            }
          })
          .finally(() => {
            record.isDoDocInRed = false;
          });
      }

      const [registerSelStampModal, { openModal: openSelectStampModal }] = useModal();
      const handleSelStamp = (record) => {
        openSelStampModal(record);
      };

      const openSelStampModal = (record) => {
        if (record) {
          openSelectStampModal(true, {
            op: 'getStampForAtt',
            ...record,
          });
        } else {
          openSelectStampModal(true, {
            op: 'getStampForForm',
          });
        }
      };

      async function handleSelStampCallBack(record) {
        console.log('handleSelStampCallBack', record);
        if (record.op == 'getStampForAtt') {
          isSpinning.value = true;
          sealDocument({
            flowId: formRowData.value.flowId,
            stampId: record.stampId,
            attachId: record.attachId,
          })
            .then((data) => {
              if (data.res == 0) {
                createMessage.success('操作成功');
              }
            })
            .finally(() => {
              isSpinning.value = false;
            });
        } else {
          await getShowImg({ path: record['imageUrl'] }).then(async (res) => {
            let imageUrl = bufToUrl(res);
            insertSignImg(record.stampId, imageUrl);
          });
        }
      }

      // 原用于图片签名框SignImgCtl，现暂已无用
      async function showImage(imgId, imgPath) {
        await getShowImg({ path: imgPath }).then(async (res) => {
          let imageUrl = bufToUrl(res);
          console.log('showImage imgId', imgId, 'imgPath', imgPath);
          findObj(imgId).src = imageUrl;
        });
      }

      const [registerInputPwdModal, { openModal: openInPwdModal }] = useModal();
      const openInputPwdModal = () => {
        openInPwdModal(true, {});
      };

      async function handleInputPwdCallBack(record) {
        setInputObjValue(record.realName + '  ' + record.date);
      }

      const [registerWritePadModal, { openModal: openWPadModal }] = useModal();
      const openWritePadModal = (fieldName, w, h) => {
        openWPadModal(true, { fieldName, w, h });
      };

      async function handleWritePadCallBack() {}

      const [registerTipPhraseModal, { openModal: openTPhraseModal }] = useModal();
      const openTipPhraseModal = () => {
        openTPhraseModal(true, {});
      };

      async function handleTipPhraseCallBack() {
        $('.phraseIcon').html('');
        fetchPhrases();
      }

      function removePhrase(id) {
        createConfirm({
          iconType: 'info',
          title: () => h('span', t('common.prompt')),
          content: () => h('span', '您确定要删除么'),
          onOk: async () => {
            await delPhrase({ id: id }).then((data) => {
              if (data.res == 0) {
                createMessage.success(t('common.opSuccess'));
                handleTipPhraseCallBack();
              }
            });
          },
        });
      }

      const [registerSelDeptModal, { openModal: openSDeptModal }] = useModal();
      const openSelDeptModal = (record) => {
        openSDeptModal(true, {
          ...record,
        });
      };

      async function handleSelDeptCallBack(record) {
        let codes = '',
          names = '';
        if (record) {
          if (record.length) {
            for (let i in record) {
              if (codes == '') {
                codes = record[i].value;
                names = record[i].label;
              } else {
                codes += ',' + record[i].value;
                names += ',' + record[i].label;
              }
            }
          } else {
            codes = record.value;
            names = record.label;
          }
        }

        console.log('handleSelDeptCallBack', record);
        console.log('names', names);
        setInputObjValue(codes, names);
      }

      const [registerLocationMarkModal, { openModal: openLMModal }] = useModal();
      const openLocationMarkModal = (record) => {
        console.log('openLocationMarkModal record', record);
        openLMModal(true, {
          ...record,
        });
      };

      async function handleLocationMarkCallBack(item) {
        setInputObjValue(item.point.lng + ',' + item.point.lat + ',' + item.address, item.address);
      }

      // 直送给返回者
      async function handleToRetuner() {
        isSpinning.value = true;
        let isToReturner = true;
        await submitResult(false, [], isToReturner);
        isSpinning.value = false;
      }

      async function handleSuspend() {
        isSpinning.value = true;
        let res = await getSuspendFlow({ myActionId: formRowData.value.myActionId });
        done(res.msg, true, '');
        isSpinning.value = false;
      }

      async function handleResume() {
        isSpinning.value = true;
        let data = await getResumeFlow({ myActionId: formRowData.value.myActionId });
        console.log('handleResume', data);
        createMessage.success('操作成功');
        if (data.newMyActionId > 0) {
          await getFlowProcessContent(data.newMyActionId);
        }
        //handleRefresh();
        isSpinning.value = false;
      }

      function closeView() {
        removeLink();
        removeScript(srcId.value);
        closeCurrent();
      }

      function handleClose() {
        emit('success');
        emit('closeDrawer');
        if (isTab.value) {
          closeView();
        }
      }

      // 映射的文件宏控件下载
      function downloadFileVisual(fileName, params) {
        getVisualDownload(params).then((data) => {
          if (data) {
            downloadByData(data, fileName);
          }
        });
      }

      const handleSelectFiles = (
        filePath,
        fieldName,
        fieldTitle,
        formCode,
        pageType,
        mainId,
        accept = '',
        multiple = false,
      ) => {
        selectFiles(
          {
            formName: getFormName.value,
            route: currentRoute.value,
            multiple: multiple,
            filePath,
            fieldName,
            fieldTitle,
            formCode,
            pageType,
            mainId,
            accept,
            validExt: flowProcessData.validExt,
            maxFileSize: flowProcessData.maxFileSize,
            myActionId: flowProcessData.myActionId,
          },
          (files) => {
            console.log('回调文件', files);
          },
        );
      };

      const handleDownloadObsFile = (key, fileName) => {
        // getObjectByKey('upfile/visual/personbasic/2023/8/4dbc0ea68968427cb.doc');
        getObjectByKey(key, fileName);
      };

      let fileNo = 0;
      //获取文件change事件
      const handleFilesChange = (info) => {
        console.log('handleFilesChange info', info);
        console.log('handleFilesChange flowProcessData.validExt', flowProcessData.validExt);
        const { file } = info;

        let fileName = file.name;
        let ext = fileName.substring(fileName.lastIndexOf('.') + 1);
        if (flowProcessData.validExt && flowProcessData.validExt.length > 0) {
          let isExtValid = flowProcessData.validExt.some(
            (item) => item.toLowerCase() == ext.toLowerCase(),
          );
          if (!isExtValid) {
            createMessage.warn('文件 ' + file.name + ' 类型非法');
            return;
          }
        }

        let maxFileSize = flowProcessData.maxFileSize;
        if (file.size > maxFileSize * 1024) {
          createMessage.warn('文件: ' + file.name + ' 大小超过了 ' + maxFileSize / 1024 + 'M');
          return;
        }

        uploadFileObjectFunc({
          files: [file],
          formName: getFormName.value,
          route: currentRoute.value,
          fieldName: 'att' + fileNo,
          filePath: flowProcessData.visualPath,
          formCode: formRowData.value.formCode,
          pageType: 'flow',
          mainId: formRowData.value.flowId,
          fieldTitle: '附件',
          myActionId: flowProcessData.myActionId,
        });

        fileNo++;
      };

      const handleRemoveFile = (file, actions) => {
        console.log('handleRemoveFile', file);
        let treeList = uploadFileStore.getUploadFileTreeList;
        treeList.forEach((item) => {
          item.children.forEach((it) => {
            console.log('it', it);
            if (it.file.uid === file.uid) {
              if (it.progress == 100) {
                let params = {
                  flowId: formRowData.value.flowId,
                  attachId: it.attId,
                };
                getDelAttach(params).then(() => {
                  deleteByUid(file.uid);

                  actions.remove();
                  reloadAttachment();
                });
              } else {
                deleteByUid(file.uid);
                actions.remove();
              }
            }
          });
        });
      };

      const uploadFileStore = useUploadFileStore();
      const getProgress = computed(() => (file: any) => {
        console.log('file', file);
        let treeList = uploadFileStore.getUploadFileTreeList;
        let progress = 100;
        treeList.forEach((item) => {
          item.children.forEach((it) => {
            console.log('it', it);
            if (it.file.uid === file.uid) {
              progress = it.progress;
              if (progress == 100) {
                console.log('getProgress', progress);
                // 此处不能调用reloadAttachment，因为progress有可能会多次被computed检测到变化，即便已经为100，而且在putUploadProgress中已经调用过了
                // reloadAttachment();
              }
            }
          });
        });
        return progress;
      });

      const getAttVisible = computed(() => (file: any) => {
        let treeList = uploadFileStore.getUploadFileTreeList;
        let isFound = false;
        treeList.forEach((item) => {
          item.children.forEach((it) => {
            console.log('getAttVisible it', it);
            // 进度为100以内，且未finishUpload并接收到attId，即上传完毕即不再显示
            if (it.file.uid === file.uid && it.progress < 100 && !it.attId) {
              isFound = true;
            }
          });
        });
        // 未找到，说明是从树形列表上删除了该节点
        return isFound;
      });

      const getAttUploadFinishedIsImg = computed(() => (file: any) => {
        let treeList = uploadFileStore.getUploadFileTreeList;
        let progress = 0;
        let isFound = false;
        let isImg = false;
        treeList.forEach((item) => {
          item.children.forEach((it) => {
            console.log('it', it);
            if (it.file.uid === file.uid) {
              progress = it.progress;
              isImg = isImage(it.fieldValue);
              isFound = true;
            }
          });
        });
        // 未找到，说明是从树形列表上删除了该节点
        if (!isFound) {
          return false;
        }
        if (progress == 100) {
          return isImg;
        }
      });

      const handleShowImgAtt = (file: any) => {
        let treeList = uploadFileStore.getUploadFileTreeList;
        let progress = 0;
        treeList.forEach((item) => {
          item.children.forEach((it) => {
            console.log('it', it);
            if (it.file.uid === file.uid) {
              progress = it.progress;
              if (progress == 100) {
                window.open(
                  serverInfo.rootPath +
                    '/showImg.do?visitKey=' +
                    it.visitKey +
                    '&path=' +
                    it.fieldValue,
                );
              }
            }
          });
        });
      };

      const isAttUploading = computed(() => (file: any) => {
        let status = UploadStatus.READY;
        let treeList = uploadFileStore.getUploadFileTreeList;
        treeList.forEach((item) => {
          item.children.forEach((it) => {
            if (it.file.uid === file.uid) {
              status = it.status;
            }
          });
        });
        return status == parseInt(UploadStatus.START);
      });

      const handleUploadPause = computed(() => (file: any) => {
        let treeList = uploadFileStore.getUploadFileTreeList;
        treeList.forEach((item) => {
          item.children.forEach((it) => {
            if (it.file.uid === file.uid) {
              it.pauseUpload();
            }
          });
        });
      });

      const isAttUploadPause = computed(() => (file: any) => {
        let status = UploadStatus.READY;
        let treeList = uploadFileStore.getUploadFileTreeList;
        treeList.forEach((item) => {
          item.children.forEach((it) => {
            if (it.file.uid === file.uid) {
              status = it.status;
            }
          });
        });
        return status == parseInt(UploadStatus.PAUSE);
      });

      // 续传
      const handleUploadStart = computed(() => (file: any) => {
        let treeList = uploadFileStore.getUploadFileTreeList;
        treeList.forEach((item) => {
          item.children.forEach((it) => {
            if (it.file.uid === file.uid) {
              it.startUpload();
            }
          });
        });
      });

      const isAttUploadStart = computed(() => (file: any) => {
        let status = UploadStatus.READY;
        let treeList = uploadFileStore.getUploadFileTreeList;
        treeList.forEach((item) => {
          item.children.forEach((it) => {
            if (it.file.uid === file.uid) {
              status = it.status;
            }
          });
        });
        return status == parseInt(UploadStatus.START);
      });

      const handleUploadCancel = computed(() => (file: any, actions) => {
        let treeList = uploadFileStore.getUploadFileTreeList;
        treeList.forEach((item) => {
          item.children.forEach((it) => {
            if (it.file.uid === file.uid) {
              it.cancelUpload();
              actions.remove();
            }
          });
        });
      });

      const getAttUploadFinishedCanPreview = computed(() => (file: any) => {
        let treeList = uploadFileStore.getUploadFileTreeList;
        let progress = 0;
        let isFound = false;
        let canPreview = false;
        treeList.forEach((item) => {
          item.children.forEach((it) => {
            console.log('getAttUploadFinishedCanPreview it', it);
            if (it.file.uid === file.uid) {
              progress = it.progress;
              canPreview = it.canPreview;
              isFound = true;
            }
          });
        });
        // 未找到，说明是从树形列表上删除了该节点
        if (!isFound) {
          return true;
        }
        if (progress == 100) {
          return canPreview;
        }
      });

      const getAttUploadFinished = computed(() => (file: any) => {
        let treeList = uploadFileStore.getUploadFileTreeList;
        let progress = 0;
        let isFound = false;
        treeList.forEach((item) => {
          item.children.forEach((it) => {
            console.log('it', it);
            if (it.file.uid === file.uid) {
              progress = it.progress;
              isFound = true;
            }
          });
        });
        // 未找到，说明是从树形列表上删除了该节点
        if (!isFound) {
          return true;
        }
        if (progress == 100) {
          return true;
        }
      });

      const handlePreviewAtt = computed(() => (file: any) => {
        let previewUrl = '';
        let treeList = uploadFileStore.getUploadFileTreeList;
        treeList.forEach((item) => {
          item.children.forEach((it) => {
            console.log('it', it);
            if (it.file.uid === file.uid) {
              previewUrl = it.previewUrl;
              if (previewUrl) {
                if (previewUrl.indexOf('#') === 0) {
                  handleWebOfficePreview({ id: it.attId, diskName: it.diskName });
                } else if (previewUrl.indexOf('&') === 0) {
                  handleOnlyofficePreview({ id: it.attId, diskName: it.diskName });
                } else {
                  window.open(previewUrl);
                }
              }
            }
          });
        });
      });

      const setUploadFileTreeListAttInfo = (
        file: any,
        attId,
        canPreview,
        previewUrl,
        visitKey,
        diskName,
      ) => {
        let treeList = uploadFileStore.getUploadFileTreeList;
        treeList.forEach((item) => {
          item.children.forEach((it) => {
            console.log('setUploadFileTreeListAttInfo it', it);
            console.log('setUploadFileTreeListAttInfo file.uid', file.uid);
            if (it.file.uid === file.uid) {
              it.attId = attId;
              it.canPreview = canPreview;
              it.previewUrl = previewUrl;
              it.visitKey = visitKey;
              it.diskName = diskName;

              console.log('setUploadFileTreeListAttInfo it2', it);
              uploadFileStore.setUploadFileTreeList(treeList);
            }
          });
        });
      };

      const handleDownloadAtt = computed(() => (file: any) => {
        const serverInfo = userStore.getServerInfo;
        // 如果是断点续传
        if (serverInfo.isUseBreakpointResume) {
          let attId = '',
            attName = '';
          let treeList = uploadFileStore.getUploadFileTreeList;
          treeList.forEach((item) => {
            item.children.forEach((it) => {
              if (it.file.uid === file.uid) {
                attId = it.attId;
                attName = it.file.name;
              }
            });
          });

          const params = {
            flowId: formRowData.value.flowId,
            attachId: attId,
          };
          getDownload(params).then((data) => {
            if (data) {
              downloadByData(data, attName);
            }
          });
          return;
        }
        let key = '';
        let treeList = uploadFileStore.getUploadFileTreeList;
        treeList.forEach((item) => {
          item.children.forEach((it) => {
            console.log('it', it);
            if (it.file.uid === file.uid) {
              key = it.fieldValue;
              handleDownloadObsFile(key, file.name);
            }
          });
        });
      });

      const [registerLocationMarkTdModal, { openModal: openLMTdModal }] = useModal();
      const openLocationMarkTdModal = (record) => {
        console.log('openLocationMarkTdModal record', record);
        openLMTdModal(true, {
          ...record,
        });
      };

      const isDownloadZip = ref(false);
      const handleDownloadZip = (record) => {
        let params = {
          flowIds: formRowData.value.flowId,
        };
        isDownloadZip.value = true;
        downloadZipFile(params).then((data) => {
          if (data) {
            downloadByData(data, `${formRowData.value.cwsWorkflowTitle}.zip`);
            isDownloadZip.value = false;
          }
        });
      };

      // 设计器，用于脚本宏控件
      const [registerModalDesignIframe, { openModal: openDesignIframe, closeModal }] = useModal();

      //设计器打开
      const openScriptDesigner = (script) => {
        openDesignIframe(true, {
          formCode: formRowData.value.formCode,
          scriptStr: script,
        });
      };
      //设计器回调
      const handleSuccessDesignIframe = (value) => {
        formRowData.value.nodeScript = value;
        try {
          setScript(value);
        } catch (e) {
          console.warn(e);
        }
      };

      const ifrmRef = ref<any>(null);
      const onMessage = (e) => {
        var d = e.data;
        var data = d.data;
        var type = d.type;
        if (type == 'setScript') {
          console.log('onMessage data', data);
          setScript(data);
          closeModal();
        } else if (type == 'getScript') {
          let serverInfo = userStore.getServerInfo;
          console.log('getScript scriptStr.value=', getScript());
          let data = {
            type: 'openerScript',
            version: serverInfo.version,
            spVersion: serverInfo.spVersion,
            scene: 'ScriptCtl',
            data: getScript(),
          };
          unref(ifrmRef)?.doPostMessage(data);
        }
      };

      if (window.addEventListener) {
        window.addEventListener('message', onMessage, false);
      }

      let btnFieldDesc = {};
      // 通过表单中的按钮发起流程
      function initFlowByBtn() {
        if (unref(isTab)) {
          // 不支持在tab状态下发起
          // handleLaunchFlowInDrawer(btnFieldDesc);
          createMessage.info('选项卡模式下不支持点击按钮发起流程');
        } else {
          emit('launchFlowAction', btnFieldDesc);
        }
      }

      async function handleBtnClick(item, btnFieldName) {
        console.log('handleBtnClick item', item);
        if (item.event === 'link') {
          item['flowId'] = formRowData.value.flowId;
          item['btnId'] = item.id;
          go({
            path: item.link,
            query: {
              ...item,
            },
          });
        }
        // 在流程中再发起另外一个流程
        else if (item.event === 'flow') {
          await toolbarSubmit(null, true);

          item['flowId'] = formRowData.value.flowId;
          item['btnId'] = item.id;
          item['btnFieldName'] = btnFieldName; // 表单中按钮的字段名

          btnFieldDesc = item;
        } else if (item.event === 'module') {
          // onClose();
          // emit('close');
          // go({
          //   path: '/smartModulePage',
          //   query: {
          //     moduleCode: item.moduleCode,
          //     moduleId: dataRecord.value['id'],
          //     btnId: item.id,
          //   },
          // });

          var json = {};
          var form = $('form[name=' + getFormName.value + ']').serializeArray();
          $.each(form, function () {
            if (this.name.indexOf('cws_textarea_') == -1) {
              if (json[this.name]) {
                if (!json[this.name].push) {
                  json[this.name] = [json[this.name]];
                }
                json[this.name].push();
              } else {
                json[this.name] = this.value || '';
              }
            }
          });

          openSmartModuleSelTableDrawer(0, 3, {
            moduleCode: item.moduleCode,
            listPageParams: { flowId: formRowData.value.flowId, btnId: item.id, ...json },
          });
        } else {
          // click事件
          try {
            eval(item['link']);
          } catch (e) {
            console.warn('handleBtnClick', e);
          }
        }
      }

      const getFileExt = (fileName) => {
        let p = fileName.lastIndexOf('.');
        if (p != -1) {
          return fileName.substring(p + 1).toLowerCase();
        }
        return fileName;
      };

      const isOfficeFile = (record) => {
        let ext = getFileExt(record.diskName);
        if (
          ext == 'doc' ||
          ext == 'docx' ||
          ext == 'xls' ||
          ext == 'xlsx' ||
          ext == 'ppt' ||
          ext == 'pptx'
        )
          return true;
        else return false;
      };

      const handleWebOfficePreview = (record) => {
        // go({
        //   path: '/webOfficePreview',
        //   query: {
        //     fileId: 'flow_' + record.id,
        //     token: flowProcessData.skey,
        //   },
        // });

        let routeUrl: any = {};
        routeUrl = resolve({
          path: '/webOffice',
          query: {
            type: 'flow',
            id: record.id,
            mode: 'r',
            actionId: formRowData.value.actionId,
            ext: getFileExt(record.diskName),
            // fileId: 'flow_' + formRowData.value.actionId + '_r_' + record.id,
            token: flowProcessData.skey,
          },
        });

        window.open(routeUrl.href);
      };

      const handleOnlyofficePreview = (record) => {
        let routeUrl: any = {};
        routeUrl = resolve({
          path: '/onlyoffice',
          query: {
            type: 'flow',
            id: record.id,
            name: record.name,
            mode: 'r',
            flowId: formRowData.value.flowId,
            actionId: formRowData.value.actionId,
            ext: getFileExt(record.diskName),
            onlyofficeServerUrl: formRowData.value.onlyofficeServerUrl,
            token: flowProcessData.skey,
          },
        });

        window.open(routeUrl.href);
      };

      const handleEditOffice = (record) => {
        if (formRowData.value.officeEditor == 'web-office') {
          let routeUrl: any = {};
          routeUrl = resolve({
            path: '/webOffice',
            query: {
              type: 'flow',
              id: record.id,
              mode: 'w',
              actionId: formRowData.value.actionId,
              ext: getFileExt(record.diskName),
              // fileId: 'flow_' + formRowData.value.actionId + '_r_' + record.id,
              token: flowProcessData.skey,
            },
          });

          window.open(routeUrl.href);
        } else {
          let routeUrl: any = {};
          routeUrl = resolve({
            path: '/onlyOffice',
            query: {
              type: 'flow',
              id: record.id,
              flowId: formRowData.value.flowId,
              name: record.name,
              mode: 'w',
              actionId: formRowData.value.actionId,
              ext: getFileExt(record.diskName),
              onlyofficeServerUrl: formRowData.value.onlyofficeServerUrl,
              token: flowProcessData.skey,
            },
          });
          window.open(routeUrl.href);
        }
      };

      function handleSelectAllOnAction(users, itemIndex) {
        users.forEach((item) => {
          item.checked = true;
        });
        toActions.value[itemIndex].xorChecked = true;
      }

      function handlePreview(record) {
        preview(record.previewUrl.substring(1));
      }

      const processTimeLineRef = ref<Nullable<HTMLElement>>(null);
      //评论结束
      const handleReplyViewSuccess = () => {
        console.log('processTimeLineRef.value', processTimeLineRef.value);
        if (processTimeLineRef.value && typeof processTimeLineRef.value.fetch == 'function') {
          processTimeLineRef.value.fetch();
        }
      };

      function handleOpenEditDrawer(record) {
        console.log('handleOpenEditDrawer record', record);
        openSmartModuleDrawer(true, {
          isUpdate: 2,
          record: {
            moduleCode: record['moduleCode'],
            id: record['id'],
            // formCode: '',
            treeNodeCode: '',
            isTreeView: false,
          },
        });
      }

      return {
        isSpinning,
        matchJson,
        selectDeptCode,
        content,
        common,
        cwsId,
        saveDraft,
        fileList,
        beforeUpload,
        handleRemove,
        registerTable,
        handleDelete,
        handleDownload,
        handleDownloadOfd,
        formRowData,
        toActions,
        registerModal,
        selectUser,
        handleCallBack,
        selectUserInForm,
        onSelDept,
        checkXOR,
        toolbarSubmit,
        matchJsonRegisterModal,
        handleMatchJsonCallBack,
        returnFlow,
        returnFlowVisible,
        handleReturnFlow,
        returnResult,
        returnIdValueRadio,
        aryReturnAction,
        isReturnStyleFree,
        registerSmartModuleRelateTableDrawer,
        smartModuleRelateTableDrawerhandleSuccess,
        registerSmartModuleSelDrawer,
        handleSmartModuleSelCallBack,
        registerFlowChartDrawer,
        openFlowChartInfoDrawer,
        handleManager,
        handleDebug,
        registerDebugDrawer,
        registerSmartModuleDrawer,
        handleSmartModuleCallBack,
        openSmartModuleDrawerForShow,
        registerProcessShowDrawer,
        handleProcessShowCallBack,
        handleProcessViewCallBack,
        handleDeBugCallBack,
        registerHandleTable,
        t,
        rawFileFn,
        importVisible,
        isImport,
        isDownload,
        handleDownloadExcelTempl,
        handleCancel,
        delFlow,
        onClickMenu,
        handlePrintBtnClick,
        registerProcessViewDrawer,
        discardFlow,
        btnAgreeName,
        btnReturnName,
        btnDisagreeName,
        btnDistributeName,
        disagreeFlow,
        finishAgreeFlow,
        typeCode,
        aryAttSize,
        initWindowFunc,
        handleRefresh,
        flowIsRemarkShow,
        flowRemarkPos,
        handleCountersign,
        registerCountersignModal,
        handleCountersignCallBack,
        handleDistribute,
        registerDistributeModal,
        handleDistributeCallBack,
        isPlusDescShow,
        delPlus,
        registerSelTemplateModal,
        handleSelTemplate,
        handleSelTemplateCallBack,
        registerSelStampModal,
        handleSelStamp,
        handleSelStampCallBack,
        registerInputPwdModal,
        handleInputPwdCallBack,
        registerWritePadModal,
        handleWritePadCallBack,
        registerTipPhraseModal,
        handleTipPhraseCallBack,
        openTipPhraseModal,
        handleToRetuner,
        handleSuspend,
        handleResume,
        registerSelDeptModal,
        handleSelDeptCallBack,
        registerLocationMarkModal,
        handleLocationMarkCallBack,
        isLoaded,
        clearSmartModuleSel,
        isDoLoading,
        getFormName,
        isReturning,
        isLaunched,
        isTab,
        handleDownloadObsFile,
        handleFilesChange,
        handleRemoveFile,
        getProgress,
        getAttUploadFinished,
        handleDownloadAtt,
        isObjStoreEnabled,
        handlePreviewAtt,
        getAttUploadFinishedCanPreview,
        getAttUploadFinishedIsImg,
        handleShowImgAtt,
        getAttVisible,
        isLoadTimeExceeded,
        registerLocationMarkTdModal,
        handleTransfer,
        currentRoute,
        handleDownloadZip,
        isDownloadZip,
        registerModalDesignIframe,
        handleSuccessDesignIframe,
        ifrmRef,
        toolbarClass,
        btnSaveName,
        btnPlusName,
        btnDelName,
        btnTransferName,
        btnSuspendName,
        btnResumeName,
        btnDiscardName,
        btnFinishAgreeName,
        btnToReturnerName,
        handleWebOfficePreview,
        handleEditOffice,
        isOfficeFile,
        readedFlow,
        btnReadedName,
        isUseBreakpointResume,
        isAttUploading,
        handleUploadPause,
        isAttUploadPause,
        handleUploadStart,
        isAttUploadStart,
        handleUploadCancel,
        handleSelectAllOnAction,
        registerProcessSelectDrawer,
        handleProcessSelect,
        handleCwsWorkflowResultChange,
        handlePreview,
        cwsIsFormLoaded,
        handleReplyViewSuccess,
        processTimeLineRef,
        activeTimeKey,
        handleOnlyofficePreview,
        matchBranchAndUserActions,
        matchBranchAndUserToActions,
        getMatchBranchAndUserData,
        approvalProcessLineRef,
        handleOpenEditDrawer,
      };
    },
  });
</script>
<style scoped>
  @import '../../../assets/css/css.css';
  /* @import '@mdi/font/css/materialdesignicons.css'; 无效*/
  ::v-deep .ant-btn-sm {
    font-size: 14px !important;
  }
  :deep(.ant-form-item) {
    margin-bottom: 5px;
  }
  :deep(.vben-basic-table .ant-table-wrapper) {
    padding-left: 0;
  }
  .toolbar-wrap {
    height: 100px;
    background-color: white;
    z-index: 100;
  }
  .toolbar {
    position: fixed;
    padding-top: 8px;
    z-index: 10;
    background-color: white;
    width: 100%;
    height: 90px;
    z-index: 100;
  }
  .toolbar-too-many {
    padding-top: 8px;
    z-index: 10;
    background-color: white;
    width: 100%;
    height: 90px;
    z-index: 100;
  }

  /* :deep(.vben-basic-drawer .ant-drawer-content .ant-drawer-body) {
    background-color: #f4f4f6 !important;
  }
  */
  /* :deep(.ant-drawer-body) {
    background-color: #fff !important;
  } */

  #flowFormBox {
    background: #f4f4f6;
    padding: 15px;
  }
</style>
<style>
  .vben-basic-drawer .ant-drawer-content .ant-drawer-body {
    background-color: #fff !important;
  }
</style>
